• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revision307951e124afc0ab385dc679a57562d339049e2b (tree)
Time2016-08-02 07:28:12
AuthorFelipe Leme <felipeal@goog...>
CommiterFelipe Leme

Log Message

Deprecated 'adb bugreport' with flat files.

Starting on Android N, zipped bugreports contain more information than
flat-file, text bugreports. On N, calls to 'adb bugreport' would still
generate a flat-file bugreport, but with a warning.

With this change, 'adb bugreport' will generate a zipped bugreport in
the current directory, using the bugreport name provided by the
device. Similarly, calling 'adb bugreport dir' will generate a bugreport
with a device-provided name, but in such directory.

BUG: 30451114
BUG: 29448020

Change-Id: Ibc8920dd44a5f62feb15bf3fefdcb0bdbf389a90

Change Summary

Incremental Difference

--- a/adb/bugreport.cpp
+++ b/adb/bugreport.cpp
@@ -14,31 +14,38 @@
1414 * limitations under the License.
1515 */
1616
17+#include "bugreport.h"
18+
1719 #include <string>
1820 #include <vector>
1921
2022 #include <android-base/strings.h>
2123
22-#include "bugreport.h"
24+#include "sysdeps.h"
25+#include "adb_utils.h"
2326 #include "file_sync_service.h"
2427
25-static constexpr char BUGZ_OK_PREFIX[] = "OK:";
26-static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
28+static constexpr char BUGZ_BEGIN_PREFIX[] = "BEGIN:";
2729 static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
2830 static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
31+static constexpr char BUGZ_OK_PREFIX[] = "OK:";
32+static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
2933
3034 // Custom callback used to handle the output of zipped bugreports.
3135 class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
3236 public:
33- BugreportStandardStreamsCallback(const std::string& dest_file, bool show_progress, Bugreport* br)
37+ BugreportStandardStreamsCallback(const std::string& dest_dir, const std::string& dest_file,
38+ bool show_progress, Bugreport* br)
3439 : br_(br),
3540 src_file_(),
41+ dest_dir_(dest_dir),
3642 dest_file_(dest_file),
37- line_message_(android::base::StringPrintf("generating %s", dest_file_.c_str())),
43+ line_message_(),
3844 invalid_lines_(),
3945 show_progress_(show_progress),
4046 status_(0),
4147 line_() {
48+ SetLineMessage();
4249 }
4350
4451 void OnStdout(const char* buffer, int length) {
@@ -80,25 +87,49 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
8087 BUGZ_FAIL_PREFIX);
8188 return -1;
8289 }
90+ std::string destination;
91+ if (dest_dir_.empty()) {
92+ destination = dest_file_;
93+ } else {
94+ destination = android::base::StringPrintf("%s%c%s", dest_dir_.c_str(),
95+ OS_PATH_SEPARATOR, dest_file_.c_str());
96+ }
8397 std::vector<const char*> srcs{src_file_.c_str()};
84- status_ = br_->DoSyncPull(srcs, dest_file_.c_str(), true, line_message_.c_str()) ? 0 : 1;
98+ status_ =
99+ br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
85100 if (status_ != 0) {
86101 fprintf(stderr,
87102 "Bug report finished but could not be copied to '%s'.\n"
88103 "Try to run 'adb pull %s <directory>'\n"
89104 "to copy it to a directory that can be written.\n",
90- dest_file_.c_str(), src_file_.c_str());
105+ destination.c_str(), src_file_.c_str());
91106 }
92107 }
93108 return status_;
94109 }
95110
96111 private:
112+ void SetLineMessage() {
113+ line_message_ =
114+ android::base::StringPrintf("generating %s", adb_basename(dest_file_).c_str());
115+ }
116+
117+ void SetSrcFile(const std::string path) {
118+ src_file_ = path;
119+ if (!dest_dir_.empty()) {
120+ // Only uses device-provided name when user passed a directory.
121+ dest_file_ = adb_basename(path);
122+ SetLineMessage();
123+ }
124+ }
125+
97126 void ProcessLine(const std::string& line) {
98127 if (line.empty()) return;
99128
100- if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
101- src_file_ = &line[strlen(BUGZ_OK_PREFIX)];
129+ if (android::base::StartsWith(line, BUGZ_BEGIN_PREFIX)) {
130+ SetSrcFile(&line[strlen(BUGZ_BEGIN_PREFIX)]);
131+ } else if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
132+ SetSrcFile(&line[strlen(BUGZ_OK_PREFIX)]);
102133 } else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
103134 const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
104135 fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
@@ -112,22 +143,38 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
112143 size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
113144 int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
114145 int total = std::stoi(line.substr(idx2 + 1));
115- br_->UpdateProgress(dest_file_, progress, total);
146+ br_->UpdateProgress(line_message_, progress, total);
116147 } else {
117148 invalid_lines_.push_back(line);
118149 }
119150 }
120151
121152 Bugreport* br_;
153+
154+ // Path of bugreport on device.
122155 std::string src_file_;
123- const std::string dest_file_;
124- const std::string line_message_;
156+
157+ // Bugreport destination on host, depending on argument passed on constructor:
158+ // - if argument is a directory, dest_dir_ is set with it and dest_file_ will be the name
159+ // of the bugreport reported by the device.
160+ // - if argument is empty, dest_dir is set as the current directory and dest_file_ will be the
161+ // name of the bugreport reported by the device.
162+ // - otherwise, dest_dir_ is not set and dest_file_ is set with the value passed on constructor.
163+ std::string dest_dir_, dest_file_;
164+
165+ // Message displayed on LinePrinter, it's updated every time the destination above change.
166+ std::string line_message_;
167+
168+ // Lines sent by bugreportz that contain invalid commands; will be displayed at the end.
125169 std::vector<std::string> invalid_lines_;
170+
171+ // Whether PROGRESS_LINES should be interpreted as progress.
126172 bool show_progress_;
173+
174+ // Overall process of the operation, as returned by Done().
127175 int status_;
128176
129- // Temporary buffer containing the characters read since the last newline
130- // (\n).
177+ // Temporary buffer containing the characters read since the last newline (\n).
131178 std::string line_;
132179
133180 DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
@@ -137,17 +184,7 @@ class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface
137184 int usage();
138185
139186 int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
140- if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
141- if (argc != 2) return usage();
142-
143- // Zipped bugreport option - will call 'bugreportz', which prints the location
144- // of the generated
145- // file, then pull it to the destination file provided by the user.
146- std::string dest_file = argv[1];
147- if (!android::base::EndsWith(argv[1], ".zip")) {
148- // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
149- dest_file += ".zip";
150- }
187+ if (argc > 2) return usage();
151188
152189 // Gets bugreportz version.
153190 std::string bugz_stderr;
@@ -156,6 +193,12 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
156193 std::string bugz_version = android::base::Trim(bugz_stderr);
157194
158195 if (status != 0 || bugz_version.empty()) {
196+ // Device does not support bugreportz: if called as 'adb bugreport', just falls out to the
197+ // flat-file version
198+ if (argc == 1) return SendShellCommand(transport_type, serial, "bugreport", false);
199+
200+ // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling
201+ // 'bugreport' would generate a lot of output the user might not be prepared to handle)
159202 fprintf(stderr,
160203 "Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
161204 "If the device runs Android M or below, try 'adb bugreport' instead.\n",
@@ -163,6 +206,33 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
163206 return status != 0 ? status : -1;
164207 }
165208
209+ std::string dest_file, dest_dir;
210+
211+ if (argc == 1) {
212+ // No args - use current directory
213+ if (!getcwd(&dest_dir)) {
214+ perror("adb: getcwd failed");
215+ return 1;
216+ }
217+ } else {
218+ // Check whether argument is a directory or file
219+ if (directory_exists(argv[1])) {
220+ dest_dir = argv[1];
221+ } else {
222+ dest_file = argv[1];
223+ }
224+ }
225+
226+ if (dest_file.empty()) {
227+ // Uses a default value until device provides the proper name
228+ dest_file = "bugreport.zip";
229+ } else {
230+ if (!android::base::EndsWith(dest_file, ".zip")) {
231+ // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
232+ dest_file += ".zip";
233+ }
234+ }
235+
166236 bool show_progress = true;
167237 std::string bugz_command = "bugreportz -p";
168238 if (bugz_version == "1.0") {
@@ -175,7 +245,7 @@ int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc,
175245 show_progress = false;
176246 bugz_command = "bugreportz";
177247 }
178- BugreportStandardStreamsCallback bugz_callback(dest_file, show_progress, this);
248+ BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this);
179249 return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
180250 }
181251
--- a/adb/bugreport_test.cpp
+++ b/adb/bugreport_test.cpp
@@ -19,6 +19,12 @@
1919 #include <gmock/gmock.h>
2020 #include <gtest/gtest.h>
2121
22+#include <android-base/strings.h>
23+#include <android-base/test_utils.h>
24+
25+#include "sysdeps.h"
26+#include "adb_utils.h"
27+
2228 using ::testing::_;
2329 using ::testing::Action;
2430 using ::testing::ActionInterface;
@@ -122,28 +128,38 @@ class BugreportMock : public Bugreport {
122128
123129 class BugreportTest : public ::testing::Test {
124130 public:
125- void SetBugreportzVersion(const std::string& version) {
131+ void SetUp() {
132+ if (!getcwd(&cwd_)) {
133+ ADD_FAILURE() << "getcwd failed: " << strerror(errno);
134+ return;
135+ }
136+ }
137+
138+ void ExpectBugreportzVersion(const std::string& version) {
126139 EXPECT_CALL(br_,
127140 SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
128141 .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
129142 WithArg<4>(ReturnCallbackDone(0))));
130143 }
131144
132- void ExpectProgress(int progress, int total) {
133- EXPECT_CALL(br_, UpdateProgress(HasSubstr("file.zip"), progress, total));
145+ void ExpectProgress(int progress, int total, const std::string& file = "file.zip") {
146+ EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress, total));
134147 }
135148
136149 BugreportMock br_;
150+ std::string cwd_; // TODO: make it static
137151 };
138152
139-// Tests when called with invalid number of argumnts
153+// Tests when called with invalid number of arguments
140154 TEST_F(BugreportTest, InvalidNumberArgs) {
141155 const char* args[1024] = {"bugreport", "to", "principal"};
142156 ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
143157 }
144158
145-// Tests the legacy 'adb bugreport' option
146-TEST_F(BugreportTest, FlatFileFormat) {
159+// Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
160+// to the flat-file format ('bugreport' binary on device)
161+TEST_F(BugreportTest, NoArgumentsPreNDevice) {
162+ ExpectBugreportzVersion("");
147163 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
148164 .WillOnce(Return(0));
149165
@@ -151,15 +167,52 @@ TEST_F(BugreportTest, FlatFileFormat) {
151167 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
152168 }
153169
154-// Tests 'adb bugreport file.zip' when it succeeds and device does not support
155-// progress.
156-TEST_F(BugreportTest, OkLegacy) {
157- SetBugreportzVersion("1.0");
170+// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
171+// save the bugreport in the current directory with the name provided by the device.
172+TEST_F(BugreportTest, NoArgumentsNDevice) {
173+ ExpectBugreportzVersion("1.0");
174+
175+ std::string dest_file =
176+ android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
177+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
178+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
179+ WithArg<4>(ReturnCallbackDone())));
180+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
181+ true, StrEq("generating da_bugreport.zip")))
182+ .WillOnce(Return(true));
183+
184+ const char* args[1024] = {"bugreport"};
185+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
186+}
187+
188+// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
189+// save the bugreport in the current directory with the name provided by the device.
190+TEST_F(BugreportTest, NoArgumentsPostNDevice) {
191+ ExpectBugreportzVersion("1.1");
192+ std::string dest_file =
193+ android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
194+ ExpectProgress(50, 100, "da_bugreport.zip");
195+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
196+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
197+ WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
198+ WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
199+ WithArg<4>(ReturnCallbackDone())));
200+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
201+ true, StrEq("generating da_bugreport.zip")))
202+ .WillOnce(Return(true));
203+
204+ const char* args[1024] = {"bugreport"};
205+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
206+}
207+
208+// Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
209+TEST_F(BugreportTest, OkNDevice) {
210+ ExpectBugreportzVersion("1.0");
158211 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
159212 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
160213 WithArg<4>(ReturnCallbackDone())));
161214 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
162- true, HasSubstr("file.zip")))
215+ true, StrEq("generating file.zip")))
163216 .WillOnce(Return(true));
164217
165218 const char* args[1024] = {"bugreport", "file.zip"};
@@ -168,14 +221,14 @@ TEST_F(BugreportTest, OkLegacy) {
168221
169222 // Tests 'adb bugreport file.zip' when it succeeds but response was sent in
170223 // multiple buffer writers and without progress updates.
171-TEST_F(BugreportTest, OkLegacySplitBuffer) {
172- SetBugreportzVersion("1.0");
224+TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
225+ ExpectBugreportzVersion("1.0");
173226 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
174227 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
175228 WithArg<4>(WriteOnStdout("/bugreport.zip")),
176229 WithArg<4>(ReturnCallbackDone())));
177230 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
178- true, HasSubstr("file.zip")))
231+ true, StrEq("generating file.zip")))
179232 .WillOnce(Return(true));
180233
181234 const char* args[1024] = {"bugreport", "file.zip"};
@@ -183,16 +236,18 @@ TEST_F(BugreportTest, OkLegacySplitBuffer) {
183236 }
184237
185238 // Tests 'adb bugreport file.zip' when it succeeds and displays progress.
186-TEST_F(BugreportTest, Ok) {
187- SetBugreportzVersion("1.1");
239+TEST_F(BugreportTest, OkProgress) {
240+ ExpectBugreportzVersion("1.1");
188241 ExpectProgress(1, 100);
189242 ExpectProgress(10, 100);
190243 ExpectProgress(50, 100);
191244 ExpectProgress(99, 100);
192245 // clang-format off
193246 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
194- // NOTE: DoAll accepts at most 10 arguments, and we have reached that limit...
247+ // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
195248 .WillOnce(DoAll(
249+ // Name might change on OK, so make sure the right one is picked.
250+ WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
196251 // Progress line in one write
197252 WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
198253 // Add some bogus lines
@@ -209,30 +264,68 @@ TEST_F(BugreportTest, Ok) {
209264 WithArg<4>(ReturnCallbackDone())));
210265 // clang-format on
211266 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
212- true, HasSubstr("file.zip")))
267+ true, StrEq("generating file.zip")))
213268 .WillOnce(Return(true));
214269
215270 const char* args[1024] = {"bugreport", "file.zip"};
216271 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
217272 }
218273
274+// Tests 'adb bugreport dir' when it succeeds and destination is a directory.
275+TEST_F(BugreportTest, OkDirectory) {
276+ ExpectBugreportzVersion("1.1");
277+ TemporaryDir td;
278+ std::string dest_file =
279+ android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
280+
281+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
282+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
283+ WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
284+ WithArg<4>(ReturnCallbackDone())));
285+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
286+ true, StrEq("generating da_bugreport.zip")))
287+ .WillOnce(Return(true));
288+
289+ const char* args[1024] = {"bugreport", td.path};
290+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
291+}
292+
219293 // Tests 'adb bugreport file' when it succeeds
220294 TEST_F(BugreportTest, OkNoExtension) {
221- SetBugreportzVersion("1.1");
295+ ExpectBugreportzVersion("1.1");
222296 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
223297 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
224298 WithArg<4>(ReturnCallbackDone())));
225299 EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
226- true, HasSubstr("file.zip")))
300+ true, StrEq("generating file.zip")))
227301 .WillOnce(Return(true));
228302
229303 const char* args[1024] = {"bugreport", "file"};
230304 ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
231305 }
232306
307+// Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
308+TEST_F(BugreportTest, OkNDeviceDirectory) {
309+ ExpectBugreportzVersion("1.0");
310+ TemporaryDir td;
311+ std::string dest_file =
312+ android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
313+
314+ EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
315+ .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
316+ WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
317+ WithArg<4>(ReturnCallbackDone())));
318+ EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
319+ true, StrEq("generating da_bugreport.zip")))
320+ .WillOnce(Return(true));
321+
322+ const char* args[1024] = {"bugreport", td.path};
323+ ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
324+}
325+
233326 // Tests 'adb bugreport file.zip' when the bugreport itself failed
234327 TEST_F(BugreportTest, BugreportzReturnedFail) {
235- SetBugreportzVersion("1.1");
328+ ExpectBugreportzVersion("1.1");
236329 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
237330 .WillOnce(
238331 DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
@@ -247,7 +340,7 @@ TEST_F(BugreportTest, BugreportzReturnedFail) {
247340 // was sent in
248341 // multiple buffer writes
249342 TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
250- SetBugreportzVersion("1.1");
343+ ExpectBugreportzVersion("1.1");
251344 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
252345 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
253346 WithArg<4>(ReturnCallbackDone())));
@@ -261,7 +354,7 @@ TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
261354 // Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
262355 // response.
263356 TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
264- SetBugreportzVersion("1.1");
357+ ExpectBugreportzVersion("1.1");
265358 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
266359 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
267360 WithArg<4>(ReturnCallbackDone())));
@@ -283,7 +376,7 @@ TEST_F(BugreportTest, BugreportzVersionFailed) {
283376
284377 // Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
285378 TEST_F(BugreportTest, BugreportzVersionEmpty) {
286- SetBugreportzVersion("");
379+ ExpectBugreportzVersion("");
287380
288381 const char* args[1024] = {"bugreport", "file.zip"};
289382 ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
@@ -291,7 +384,7 @@ TEST_F(BugreportTest, BugreportzVersionEmpty) {
291384
292385 // Tests 'adb bugreport file.zip' when the main bugreportz command failed
293386 TEST_F(BugreportTest, BugreportzFailed) {
294- SetBugreportzVersion("1.1");
387+ ExpectBugreportzVersion("1.1");
295388 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
296389 .WillOnce(Return(666));
297390
@@ -301,7 +394,7 @@ TEST_F(BugreportTest, BugreportzFailed) {
301394
302395 // Tests 'adb bugreport file.zip' when the bugreport could not be pulled
303396 TEST_F(BugreportTest, PullFails) {
304- SetBugreportzVersion("1.1");
397+ ExpectBugreportzVersion("1.1");
305398 EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
306399 .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
307400 WithArg<4>(ReturnCallbackDone())));
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -81,6 +81,7 @@ static std::string product_file(const char *extra) {
8181
8282 static void help() {
8383 fprintf(stderr, "%s\n", adb_version().c_str());
84+ // clang-format off
8485 fprintf(stderr,
8586 " -a - directs adb to listen on all interfaces for a connection\n"
8687 " -d - directs command to the only connected USB device\n"
@@ -173,9 +174,11 @@ static void help() {
173174 " (-g: grant all runtime permissions)\n"
174175 " adb uninstall [-k] <package> - remove this app package from the device\n"
175176 " ('-k' means keep the data and cache directories)\n"
176- " adb bugreport [<zip_file>] - return all information from the device\n"
177- " that should be included in a bug report.\n"
178- "\n"
177+ " adb bugreport [<path>] - return all information from the device that should be included in a zipped bug report.\n"
178+ " If <path> is a file, the bug report will be saved as that file.\n"
179+ " If <path> is a directory, the bug report will be saved in that directory with the name provided by the device.\n"
180+ " If <path> is omitted, the bug report will be saved in the current directory with the name provided by the device.\n"
181+ " NOTE: if the device does not support zipped bug reports, the bug report will be output on stdout.\n"
179182 " adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
180183 " - write an archive of the device's data to <file>.\n"
181184 " If no -f option is supplied then the data is written\n"
@@ -249,8 +252,8 @@ static void help() {
249252 " ADB_TRACE - Print debug information. A comma separated list of the following values\n"
250253 " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
251254 " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
252- " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
253- );
255+ " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n");
256+ // clang-format on
254257 }
255258
256259 int usage() {
@@ -1327,7 +1330,7 @@ static std::string find_product_out_path(const std::string& hint) {
13271330 if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) {
13281331 std::string cwd;
13291332 if (!getcwd(&cwd)) {
1330- fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
1333+ perror("adb: getcwd failed");
13311334 return "";
13321335 }
13331336 return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());