Add bugreport pre-dump functionality
Allow apps to trigger the dump of certain critical data, e.g. data stored in short
ring buffers that might get lost by the time a bugreport is requested.
Then, a bugreport request can specify whether the pre-dumped data should be used.
Fixes: 205138504
Test: atest com.android.os.bugreports.tests.BugreportManagerTest
Ignore-AOSP-First: depends on changes (surfaceflinger) that cannot go into AOSP
Change-Id: I976f2ed3189e83f5bd71dc81e20306527c411d10
diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
index 28e5ee2..b091c8e 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -497,14 +497,17 @@
// Prepare arguments
unique_fd bugreport_fd(OpenForWrite("/bugreports/tmp.zip"));
unique_fd screenshot_fd(OpenForWrite("/bugreports/tmp.png"));
+ int flags = 0;
EXPECT_NE(bugreport_fd.get(), -1);
EXPECT_NE(screenshot_fd.get(), -1);
sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout))));
android::binder::Status status =
- ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
- Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener, true);
+ ds_binder->startBugreport(123, "com.example.package", std::move(bugreport_fd),
+ std::move(screenshot_fd),
+ Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, flags, listener,
+ true);
// startBugreport is an async call. Verify binder call succeeded first, then wait till listener
// gets expected callbacks.
EXPECT_TRUE(status.isOk());
@@ -532,6 +535,7 @@
// Prepare arguments
unique_fd bugreport_fd(OpenForWrite("/data/local/tmp/tmp.zip"));
unique_fd screenshot_fd(OpenForWrite("/data/local/tmp/tmp.png"));
+ int flags = 0;
EXPECT_NE(bugreport_fd.get(), -1);
EXPECT_NE(screenshot_fd.get(), -1);
@@ -539,9 +543,9 @@
// Call startBugreport with bad arguments.
sp<DumpstateListener> listener(new DumpstateListener(dup(fileno(stdout))));
android::binder::Status status =
- ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
- 2000, // invalid bugreport mode
- listener, false);
+ ds_binder->startBugreport(123, "com.example.package", std::move(bugreport_fd),
+ std::move(screenshot_fd), 2000, // invalid bugreport mode
+ flags, listener, false);
EXPECT_EQ(listener->getErrorCode(), IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT);
// The service should have died, freeing itself up for a new invocation.
@@ -563,6 +567,7 @@
unique_fd bugreport_fd2(dup(bugreport_fd.get()));
unique_fd screenshot_fd(OpenForWrite("/data/local/tmp/tmp.png"));
unique_fd screenshot_fd2(dup(screenshot_fd.get()));
+ int flags = 0;
EXPECT_NE(bugreport_fd.get(), -1);
EXPECT_NE(bugreport_fd2.get(), -1);
@@ -571,14 +576,18 @@
sp<DumpstateListener> listener1(new DumpstateListener(dup(fileno(stdout))));
android::binder::Status status =
- ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd), std::move(screenshot_fd),
- Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener1, true);
+ ds_binder->startBugreport(123, "com.example.package", std::move(bugreport_fd),
+ std::move(screenshot_fd),
+ Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, flags, listener1,
+ true);
EXPECT_TRUE(status.isOk());
// try to make another call to startBugreport. This should fail.
sp<DumpstateListener> listener2(new DumpstateListener(dup(fileno(stdout))));
- status = ds_binder->startBugreport(123, "com.dummy.package", std::move(bugreport_fd2), std::move(screenshot_fd2),
- Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, listener2, true);
+ status = ds_binder->startBugreport(123, "com.example.package", std::move(bugreport_fd2),
+ std::move(screenshot_fd2),
+ Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, flags,
+ listener2, true);
EXPECT_FALSE(status.isOk());
WaitTillExecutionComplete(listener2.get());
EXPECT_EQ(listener2->getErrorCode(),
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 70b4e5c..1ffcafa 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -31,6 +31,7 @@
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
+#include <filesystem>
#include <thread>
#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
@@ -237,7 +238,7 @@
}
TEST_F(DumpOptionsTest, InitializeFullBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, fd, fd, true);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_FULL, 0, fd, fd, true);
EXPECT_TRUE(options_.do_screenshot);
// Other options retain default values
@@ -251,7 +252,7 @@
}
TEST_F(DumpOptionsTest, InitializeInteractiveBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, fd, fd, true);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE, 0, fd, fd, true);
EXPECT_TRUE(options_.do_progress_updates);
EXPECT_TRUE(options_.do_screenshot);
@@ -265,7 +266,7 @@
}
TEST_F(DumpOptionsTest, InitializeRemoteBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, fd, fd, false);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_REMOTE, 0, fd, fd, false);
EXPECT_TRUE(options_.is_remote_mode);
EXPECT_FALSE(options_.do_vibrate);
EXPECT_FALSE(options_.do_screenshot);
@@ -279,7 +280,7 @@
}
TEST_F(DumpOptionsTest, InitializeWearBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, fd, fd, true);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WEAR, 0, fd, fd, true);
EXPECT_TRUE(options_.do_screenshot);
EXPECT_TRUE(options_.do_progress_updates);
@@ -294,7 +295,7 @@
}
TEST_F(DumpOptionsTest, InitializeTelephonyBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, fd, fd, false);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_TELEPHONY, 0, fd, fd, false);
EXPECT_FALSE(options_.do_screenshot);
EXPECT_TRUE(options_.telephony_only);
EXPECT_TRUE(options_.do_progress_updates);
@@ -309,7 +310,7 @@
}
TEST_F(DumpOptionsTest, InitializeWifiBugReport) {
- options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, fd, fd, false);
+ options_.Initialize(Dumpstate::BugreportMode::BUGREPORT_WIFI, 0, fd, fd, false);
EXPECT_FALSE(options_.do_screenshot);
EXPECT_TRUE(options_.wifi_only);
@@ -982,6 +983,19 @@
EXPECT_FALSE(ds.dump_pool_);
}
+TEST_F(DumpstateBaseTest, PreDumpUiData) {
+ // SurfaceFlinger's transactions trace is always enabled, i.e. it is always pre-dumped
+ static const auto kTransactionsTrace =
+ std::filesystem::path {"/data/misc/wmtrace/transactions_trace.winscope"};
+
+ std::system(("rm " + kTransactionsTrace.string()).c_str());
+ EXPECT_FALSE(std::filesystem::exists(kTransactionsTrace));
+
+ Dumpstate& ds_ = Dumpstate::GetInstance();
+ ds_.PreDumpUiData();
+ EXPECT_TRUE(std::filesystem::exists(kTransactionsTrace));
+}
+
class ZippedBugReportStreamTest : public DumpstateBaseTest {
public:
void SetUp() {
@@ -1045,11 +1059,6 @@
VerifyEntry(handle_, bugreport_txt_name, &entry);
}
-class DumpstateServiceTest : public DumpstateBaseTest {
- public:
- DumpstateService dss;
-};
-
class ProgressTest : public DumpstateBaseTest {
public:
Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {