Add hwbinder dev node permissions.
am: f5110ea029
Change-Id: I67ee1a3ca8a1e226f7487b33fda21943ca77b696
diff --git a/adb/Android.mk b/adb/Android.mk
index 0114ca3..063f61d 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -183,10 +183,6 @@
LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS)
LOCAL_SRC_FILES := \
$(LIBADB_TEST_SRCS) \
- adb_client.cpp \
- bugreport.cpp \
- bugreport_test.cpp \
- line_printer.cpp \
services.cpp \
shell_service_protocol.cpp \
shell_service_protocol_test.cpp \
@@ -202,7 +198,6 @@
libcrypto \
libcutils \
libdiagnose_usb \
- libgmock_host \
# Set entrypoint to wmain from sysdeps_win32.cpp instead of main
LOCAL_LDFLAGS_windows := -municode
@@ -231,7 +226,6 @@
LOCAL_SRC_FILES := \
adb_client.cpp \
- bugreport.cpp \
client/main.cpp \
console.cpp \
commandline.cpp \
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 056dbef..9ae3f1c 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -48,9 +48,9 @@
#include "transport.h"
#if !ADB_HOST
-#include <cutils/properties.h>
#include <sys/capability.h>
#include <sys/mount.h>
+#include <android-base/properties.h>
#endif
std::string adb_version() {
@@ -200,11 +200,9 @@
"ro.product.device",
};
- for (const auto& prop_name : cnxn_props) {
- char value[PROPERTY_VALUE_MAX];
- property_get(prop_name, value, "");
- connection_properties.push_back(
- android::base::StringPrintf("%s=%s", prop_name, value));
+ for (const auto& prop : cnxn_props) {
+ std::string value = std::string(prop) + "=" + android::base::GetProperty(prop, "");
+ connection_properties.push_back(value);
}
#endif
diff --git a/adb/adb.h b/adb/adb.h
index 0b9fe5b..5ff4571 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -202,6 +202,8 @@
int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
#endif
+int adb_commandline(int argc, const char **argv);
+
ConnectionState connection_state(atransport *t);
extern const char* adb_device_banner;
diff --git a/adb/adb_client.h b/adb/adb_client.h
index d35d705..9e6f1c2 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -18,7 +18,6 @@
#define _ADB_CLIENT_H_
#include "adb.h"
-#include "sysdeps.h"
#include "transport.h"
#include <string>
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
index 62900c0..369dec9 100644
--- a/adb/adb_trace.cpp
+++ b/adb/adb_trace.cpp
@@ -27,7 +27,7 @@
#include "adb.h"
#if !ADB_HOST
-#include <cutils/properties.h>
+#include <android-base/properties.h>
#endif
#if !ADB_HOST
@@ -88,19 +88,11 @@
return std::string(setting);
}
-#if !ADB_HOST
-std::string get_trace_setting_from_prop() {
- char buf[PROPERTY_VALUE_MAX];
- property_get("persist.adb.trace_mask", buf, "");
- return std::string(buf);
-}
-#endif
-
std::string get_trace_setting() {
#if ADB_HOST
return get_trace_setting_from_env();
#else
- return get_trace_setting_from_prop();
+ return android::base::GetProperty("persist.adb.trace_mask", "");
#endif
}
diff --git a/adb/bugreport.cpp b/adb/bugreport.cpp
deleted file mode 100644
index c348dd5..0000000
--- a/adb/bugreport.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define TRACE_TAG ADB
-
-#include "bugreport.h"
-
-#include <string>
-#include <vector>
-
-#include <android-base/strings.h>
-
-#include "sysdeps.h"
-#include "adb_utils.h"
-#include "file_sync_service.h"
-
-static constexpr char BUGZ_BEGIN_PREFIX[] = "BEGIN:";
-static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
-static constexpr char BUGZ_PROGRESS_SEPARATOR[] = "/";
-static constexpr char BUGZ_OK_PREFIX[] = "OK:";
-static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
-
-// Custom callback used to handle the output of zipped bugreports.
-class BugreportStandardStreamsCallback : public StandardStreamsCallbackInterface {
- public:
- BugreportStandardStreamsCallback(const std::string& dest_dir, const std::string& dest_file,
- bool show_progress, Bugreport* br)
- : br_(br),
- src_file_(),
- dest_dir_(dest_dir),
- dest_file_(dest_file),
- line_message_(),
- invalid_lines_(),
- show_progress_(show_progress),
- status_(0),
- line_() {
- SetLineMessage("generating");
- }
-
- void OnStdout(const char* buffer, int length) {
- for (int i = 0; i < length; i++) {
- char c = buffer[i];
- if (c == '\n') {
- ProcessLine(line_);
- line_.clear();
- } else {
- line_.append(1, c);
- }
- }
- }
-
- void OnStderr(const char* buffer, int length) {
- OnStream(nullptr, stderr, buffer, length);
- }
- int Done(int unused_) {
- // Process remaining line, if any.
- ProcessLine(line_);
-
- // Warn about invalid lines, if any.
- if (!invalid_lines_.empty()) {
- fprintf(stderr,
- "WARNING: bugreportz generated %zu line(s) with unknown commands, "
- "device might not support zipped bugreports:\n",
- invalid_lines_.size());
- for (const auto& line : invalid_lines_) {
- fprintf(stderr, "\t%s\n", line.c_str());
- }
- fprintf(stderr,
- "If the zipped bugreport was not generated, try 'adb bugreport' instead.\n");
- }
-
- // Pull the generated bug report.
- if (status_ == 0) {
- if (src_file_.empty()) {
- fprintf(stderr, "bugreportz did not return a '%s' or '%s' line\n", BUGZ_OK_PREFIX,
- BUGZ_FAIL_PREFIX);
- return -1;
- }
- std::string destination;
- if (dest_dir_.empty()) {
- destination = dest_file_;
- } else {
- destination = android::base::StringPrintf("%s%c%s", dest_dir_.c_str(),
- OS_PATH_SEPARATOR, dest_file_.c_str());
- }
- std::vector<const char*> srcs{src_file_.c_str()};
- SetLineMessage("pulling");
- status_ =
- br_->DoSyncPull(srcs, destination.c_str(), true, line_message_.c_str()) ? 0 : 1;
- if (status_ != 0) {
- fprintf(stderr,
- "Bug report finished but could not be copied to '%s'.\n"
- "Try to run 'adb pull %s <directory>'\n"
- "to copy it to a directory that can be written.\n",
- destination.c_str(), src_file_.c_str());
- }
- }
- return status_;
- }
-
- private:
- void SetLineMessage(const std::string& action) {
- line_message_ = action + " " + adb_basename(dest_file_);
- }
-
- void SetSrcFile(const std::string path) {
- src_file_ = path;
- if (!dest_dir_.empty()) {
- // Only uses device-provided name when user passed a directory.
- dest_file_ = adb_basename(path);
- SetLineMessage("generating");
- }
- }
-
- void ProcessLine(const std::string& line) {
- if (line.empty()) return;
-
- if (android::base::StartsWith(line, BUGZ_BEGIN_PREFIX)) {
- SetSrcFile(&line[strlen(BUGZ_BEGIN_PREFIX)]);
- } else if (android::base::StartsWith(line, BUGZ_OK_PREFIX)) {
- SetSrcFile(&line[strlen(BUGZ_OK_PREFIX)]);
- } else if (android::base::StartsWith(line, BUGZ_FAIL_PREFIX)) {
- const char* error_message = &line[strlen(BUGZ_FAIL_PREFIX)];
- fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
- status_ = -1;
- } else if (show_progress_ && android::base::StartsWith(line, BUGZ_PROGRESS_PREFIX)) {
- // progress_line should have the following format:
- //
- // BUGZ_PROGRESS_PREFIX:PROGRESS/TOTAL
- //
- size_t idx1 = line.rfind(BUGZ_PROGRESS_PREFIX) + strlen(BUGZ_PROGRESS_PREFIX);
- size_t idx2 = line.rfind(BUGZ_PROGRESS_SEPARATOR);
- int progress = std::stoi(line.substr(idx1, (idx2 - idx1)));
- int total = std::stoi(line.substr(idx2 + 1));
- br_->UpdateProgress(line_message_, progress, total);
- } else {
- invalid_lines_.push_back(line);
- }
- }
-
- Bugreport* br_;
-
- // Path of bugreport on device.
- std::string src_file_;
-
- // Bugreport destination on host, depending on argument passed on constructor:
- // - if argument is a directory, dest_dir_ is set with it and dest_file_ will be the name
- // of the bugreport reported by the device.
- // - if argument is empty, dest_dir is set as the current directory and dest_file_ will be the
- // name of the bugreport reported by the device.
- // - otherwise, dest_dir_ is not set and dest_file_ is set with the value passed on constructor.
- std::string dest_dir_, dest_file_;
-
- // Message displayed on LinePrinter, it's updated every time the destination above change.
- std::string line_message_;
-
- // Lines sent by bugreportz that contain invalid commands; will be displayed at the end.
- std::vector<std::string> invalid_lines_;
-
- // Whether PROGRESS_LINES should be interpreted as progress.
- bool show_progress_;
-
- // Overall process of the operation, as returned by Done().
- int status_;
-
- // Temporary buffer containing the characters read since the last newline (\n).
- std::string line_;
-
- DISALLOW_COPY_AND_ASSIGN(BugreportStandardStreamsCallback);
-};
-
-// Implemented in commandline.cpp
-int usage();
-
-int Bugreport::DoIt(TransportType transport_type, const char* serial, int argc, const char** argv) {
- if (argc > 2) return usage();
-
- // Gets bugreportz version.
- std::string bugz_stdout, bugz_stderr;
- DefaultStandardStreamsCallback version_callback(&bugz_stdout, &bugz_stderr);
- int status = SendShellCommand(transport_type, serial, "bugreportz -v", false, &version_callback);
- std::string bugz_version = android::base::Trim(bugz_stderr);
- std::string bugz_output = android::base::Trim(bugz_stdout);
-
- if (status != 0 || bugz_version.empty()) {
- D("'bugreportz' -v results: status=%d, stdout='%s', stderr='%s'", status,
- bugz_output.c_str(), bugz_version.c_str());
- if (argc == 1) {
- // Device does not support bugreportz: if called as 'adb bugreport', just falls out to
- // the flat-file version.
- fprintf(stderr,
- "Failed to get bugreportz version, which is only available on devices "
- "running Android 7.0 or later.\nTrying a plain-text bug report instead.\n");
- return SendShellCommand(transport_type, serial, "bugreport", false);
- }
-
- // But if user explicitly asked for a zipped bug report, fails instead (otherwise calling
- // 'bugreport' would generate a lot of output the user might not be prepared to handle).
- fprintf(stderr,
- "Failed to get bugreportz version: 'bugreportz -v' returned '%s' (code %d).\n"
- "If the device does not run Android 7.0 or above, try 'adb bugreport' instead.\n",
- bugz_output.c_str(), status);
- return status != 0 ? status : -1;
- }
-
- std::string dest_file, dest_dir;
-
- if (argc == 1) {
- // No args - use current directory
- if (!getcwd(&dest_dir)) {
- perror("adb: getcwd failed");
- return 1;
- }
- } else {
- // Check whether argument is a directory or file
- if (directory_exists(argv[1])) {
- dest_dir = argv[1];
- } else {
- dest_file = argv[1];
- }
- }
-
- if (dest_file.empty()) {
- // Uses a default value until device provides the proper name
- dest_file = "bugreport.zip";
- } else {
- if (!android::base::EndsWith(dest_file, ".zip")) {
- // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
- dest_file += ".zip";
- }
- }
-
- bool show_progress = true;
- std::string bugz_command = "bugreportz -p";
- if (bugz_version == "1.0") {
- // 1.0 does not support progress notifications, so print a disclaimer
- // message instead.
- fprintf(stderr,
- "Bugreport is in progress and it could take minutes to complete.\n"
- "Please be patient and do not cancel or disconnect your device "
- "until it completes.\n");
- show_progress = false;
- bugz_command = "bugreportz";
- }
- BugreportStandardStreamsCallback bugz_callback(dest_dir, dest_file, show_progress, this);
- return SendShellCommand(transport_type, serial, bugz_command, false, &bugz_callback);
-}
-
-void Bugreport::UpdateProgress(const std::string& message, int progress, int total) {
- int progress_percentage = (progress * 100 / total);
- line_printer_.Print(
- android::base::StringPrintf("[%3d%%] %s", progress_percentage, message.c_str()),
- LinePrinter::INFO);
-}
-
-int Bugreport::SendShellCommand(TransportType transport_type, const char* serial,
- const std::string& command, bool disable_shell_protocol,
- StandardStreamsCallbackInterface* callback) {
- return send_shell_command(transport_type, serial, command, disable_shell_protocol, callback);
-}
-
-bool Bugreport::DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
- const char* name) {
- return do_sync_pull(srcs, dst, copy_attrs, name);
-}
diff --git a/adb/bugreport.h b/adb/bugreport.h
deleted file mode 100644
index ee99cbc..0000000
--- a/adb/bugreport.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BUGREPORT_H
-#define BUGREPORT_H
-
-#include <vector>
-
-#include "adb.h"
-#include "commandline.h"
-#include "line_printer.h"
-
-class Bugreport {
- friend class BugreportStandardStreamsCallback;
-
- public:
- Bugreport() : line_printer_() {
- }
- int DoIt(TransportType transport_type, const char* serial, int argc, const char** argv);
-
- protected:
- // Functions below are abstractions of external functions so they can be
- // mocked on tests.
- virtual int SendShellCommand(
- TransportType transport_type, const char* serial, const std::string& command,
- bool disable_shell_protocol,
- StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
-
- virtual bool DoSyncPull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
- const char* name);
-
- private:
- virtual void UpdateProgress(const std::string& file_name, int progress, int total);
- LinePrinter line_printer_;
- DISALLOW_COPY_AND_ASSIGN(Bugreport);
-};
-
-#endif // BUGREPORT_H
diff --git a/adb/bugreport_test.cpp b/adb/bugreport_test.cpp
deleted file mode 100644
index 1129285..0000000
--- a/adb/bugreport_test.cpp
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bugreport.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <android-base/strings.h>
-#include <android-base/test_utils.h>
-
-#include "sysdeps.h"
-#include "adb_utils.h"
-
-using ::testing::_;
-using ::testing::Action;
-using ::testing::ActionInterface;
-using ::testing::DoAll;
-using ::testing::ElementsAre;
-using ::testing::HasSubstr;
-using ::testing::MakeAction;
-using ::testing::Return;
-using ::testing::StrEq;
-using ::testing::WithArg;
-using ::testing::internal::CaptureStderr;
-using ::testing::internal::CaptureStdout;
-using ::testing::internal::GetCapturedStderr;
-using ::testing::internal::GetCapturedStdout;
-
-// Empty function so tests don't need to be linked against file_sync_service.cpp, which requires
-// SELinux and its transitive dependencies...
-bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
- const char* name) {
- ADD_FAILURE() << "do_sync_pull() should have been mocked";
- return false;
-}
-
-// Empty functions so tests don't need to be linked against commandline.cpp
-DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
-int usage() {
- return -42;
-}
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
- bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
- ADD_FAILURE() << "send_shell_command() should have been mocked";
- return -42;
-}
-
-enum StreamType {
- kStreamStdout,
- kStreamStderr,
-};
-
-// gmock black magic to provide a WithArg<4>(WriteOnStdout(output)) matcher
-typedef void OnStandardStreamsCallbackFunction(StandardStreamsCallbackInterface*);
-
-class OnStandardStreamsCallbackAction : public ActionInterface<OnStandardStreamsCallbackFunction> {
- public:
- explicit OnStandardStreamsCallbackAction(StreamType type, const std::string& output)
- : type_(type), output_(output) {
- }
- virtual Result Perform(const ArgumentTuple& args) {
- if (type_ == kStreamStdout) {
- ::std::tr1::get<0>(args)->OnStdout(output_.c_str(), output_.size());
- }
- if (type_ == kStreamStderr) {
- ::std::tr1::get<0>(args)->OnStderr(output_.c_str(), output_.size());
- }
- }
-
- private:
- StreamType type_;
- std::string output_;
-};
-
-// Matcher used to emulated StandardStreamsCallbackInterface.OnStdout(buffer,
-// length)
-Action<OnStandardStreamsCallbackFunction> WriteOnStdout(const std::string& output) {
- return MakeAction(new OnStandardStreamsCallbackAction(kStreamStdout, output));
-}
-
-// Matcher used to emulated StandardStreamsCallbackInterface.OnStderr(buffer,
-// length)
-Action<OnStandardStreamsCallbackFunction> WriteOnStderr(const std::string& output) {
- return MakeAction(new OnStandardStreamsCallbackAction(kStreamStderr, output));
-}
-
-typedef int CallbackDoneFunction(StandardStreamsCallbackInterface*);
-
-class CallbackDoneAction : public ActionInterface<CallbackDoneFunction> {
- public:
- explicit CallbackDoneAction(int status) : status_(status) {
- }
- virtual Result Perform(const ArgumentTuple& args) {
- int status = ::std::tr1::get<0>(args)->Done(status_);
- return status;
- }
-
- private:
- int status_;
-};
-
-// Matcher used to emulated StandardStreamsCallbackInterface.Done(status)
-Action<CallbackDoneFunction> ReturnCallbackDone(int status = -1337) {
- return MakeAction(new CallbackDoneAction(status));
-}
-
-class BugreportMock : public Bugreport {
- public:
- MOCK_METHOD5(SendShellCommand,
- int(TransportType transport_type, const char* serial, const std::string& command,
- bool disable_shell_protocol, StandardStreamsCallbackInterface* callback));
- MOCK_METHOD4(DoSyncPull, bool(const std::vector<const char*>& srcs, const char* dst,
- bool copy_attrs, const char* name));
- MOCK_METHOD3(UpdateProgress, void(const std::string&, int, int));
-};
-
-class BugreportTest : public ::testing::Test {
- public:
- void SetUp() {
- if (!getcwd(&cwd_)) {
- ADD_FAILURE() << "getcwd failed: " << strerror(errno);
- return;
- }
- }
-
- void ExpectBugreportzVersion(const std::string& version) {
- EXPECT_CALL(br_,
- SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStderr(version.c_str())),
- WithArg<4>(ReturnCallbackDone(0))));
- }
-
- void ExpectProgress(int progress, int total, const std::string& file = "file.zip") {
- EXPECT_CALL(br_, UpdateProgress(StrEq("generating " + file), progress, total));
- }
-
- BugreportMock br_;
- std::string cwd_; // TODO: make it static
-};
-
-// Tests when called with invalid number of arguments
-TEST_F(BugreportTest, InvalidNumberArgs) {
- const char* args[] = {"bugreport", "to", "principal"};
- ASSERT_EQ(-42, br_.DoIt(kTransportLocal, "HannibalLecter", 3, args));
-}
-
-// Tests the 'adb bugreport' option when the device does not support 'bugreportz' - it falls back
-// to the flat-file format ('bugreport' binary on device)
-TEST_F(BugreportTest, NoArgumentsPreNDevice) {
- // clang-format off
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStderr("")),
- // Write some bogus output on stdout to make sure it's ignored
- WithArg<4>(WriteOnStdout("Dude, where is my bugreportz?")),
- WithArg<4>(ReturnCallbackDone(0))));
- // clang-format on
- std::string bugreport = "Reported the bug was.";
- CaptureStdout();
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreport", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout(bugreport)), Return(0)));
-
- const char* args[] = {"bugreport"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
- ASSERT_THAT(GetCapturedStdout(), StrEq(bugreport));
-}
-
-// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.0 - it will
-// save the bugreport in the current directory with the name provided by the device.
-TEST_F(BugreportTest, NoArgumentsNDevice) {
- ExpectBugreportzVersion("1.0");
-
- std::string dest_file =
- android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("pulling da_bugreport.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
-}
-
-// Tests the 'adb bugreport' option when the device supports 'bugreportz' version 1.1 - it will
-// save the bugreport in the current directory with the name provided by the device.
-TEST_F(BugreportTest, NoArgumentsPostNDevice) {
- ExpectBugreportzVersion("1.1");
- std::string dest_file =
- android::base::StringPrintf("%s%cda_bugreport.zip", cwd_.c_str(), OS_PATH_SEPARATOR);
- ExpectProgress(50, 100, "da_bugreport.zip");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
- WithArg<4>(WriteOnStdout("PROGRESS:50/100\n")),
- WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip\n")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("pulling da_bugreport.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 1, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and device does not support progress.
-TEST_F(BugreportTest, OkNDevice) {
- ExpectBugreportzVersion("1.0");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("pulling file.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds but response was sent in
-// multiple buffer writers and without progress updates.
-TEST_F(BugreportTest, OkNDeviceSplitBuffer) {
- ExpectBugreportzVersion("1.0");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device")),
- WithArg<4>(WriteOnStdout("/bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("pulling file.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when it succeeds and displays progress.
-TEST_F(BugreportTest, OkProgress) {
- ExpectBugreportzVersion("1.1");
- ExpectProgress(1, 100);
- ExpectProgress(10, 100);
- ExpectProgress(50, 100);
- ExpectProgress(99, 100);
- // clang-format off
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- // NOTE: DoAll accepts at most 10 arguments, and we're almost reached that limit...
- .WillOnce(DoAll(
- // Name might change on OK, so make sure the right one is picked.
- WithArg<4>(WriteOnStdout("BEGIN:/device/bugreport___NOT.zip\n")),
- // Progress line in one write
- WithArg<4>(WriteOnStdout("PROGRESS:1/100\n")),
- // Add some bogus lines
- WithArg<4>(WriteOnStdout("\nDUDE:SWEET\n\nBLA\n\nBLA\nBLA\n\n")),
- // Multiple progress lines in one write
- WithArg<4>(WriteOnStdout("PROGRESS:10/100\nPROGRESS:50/100\n")),
- // Progress line in multiple writes
- WithArg<4>(WriteOnStdout("PROG")),
- WithArg<4>(WriteOnStdout("RESS:99")),
- WithArg<4>(WriteOnStdout("/100\n")),
- // Split last message as well, just in case
- WithArg<4>(WriteOnStdout("OK:/device/bugreport")),
- WithArg<4>(WriteOnStdout(".zip")),
- WithArg<4>(ReturnCallbackDone())));
- // clang-format on
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("pulling file.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport dir' when it succeeds and destination is a directory.
-TEST_F(BugreportTest, OkDirectory) {
- ExpectBugreportzVersion("1.1");
- TemporaryDir td;
- std::string dest_file =
- android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
-
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
- WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("pulling da_bugreport.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", td.path};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file' when it succeeds
-TEST_F(BugreportTest, OkNoExtension) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip\n")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, StrEq("pulling file.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", "file"};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport dir' when it succeeds and destination is a directory and device runs N.
-TEST_F(BugreportTest, OkNDeviceDirectory) {
- ExpectBugreportzVersion("1.0");
- TemporaryDir td;
- std::string dest_file =
- android::base::StringPrintf("%s%cda_bugreport.zip", td.path, OS_PATH_SEPARATOR);
-
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("BEGIN:/device/da_bugreport.zip\n")),
- WithArg<4>(WriteOnStdout("OK:/device/da_bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/da_bugreport.zip")), StrEq(dest_file),
- true, StrEq("pulling da_bugreport.zip")))
- .WillOnce(Return(true));
-
- const char* args[] = {"bugreport", td.path};
- ASSERT_EQ(0, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport itself failed
-TEST_F(BugreportTest, BugreportzReturnedFail) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(
- DoAll(WithArg<4>(WriteOnStdout("FAIL:D'OH!\n")), WithArg<4>(ReturnCallbackDone())));
-
- CaptureStderr();
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
- ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport itself failed but response
-// was sent in
-// multiple buffer writes
-TEST_F(BugreportTest, BugreportzReturnedFailSplitBuffer) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("FAIL")), WithArg<4>(WriteOnStdout(":D'OH!\n")),
- WithArg<4>(ReturnCallbackDone())));
-
- CaptureStderr();
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
- ASSERT_THAT(GetCapturedStderr(), HasSubstr("D'OH!"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz returned an unsupported
-// response.
-TEST_F(BugreportTest, BugreportzReturnedUnsupported) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("bugreportz? What am I, a zombie?")),
- WithArg<4>(ReturnCallbackDone())));
-
- CaptureStderr();
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
- ASSERT_THAT(GetCapturedStderr(), HasSubstr("bugreportz? What am I, a zombie?"));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz -v command failed
-TEST_F(BugreportTest, BugreportzVersionFailed) {
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -v", false, _))
- .WillOnce(Return(666));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreportz -v returns status 0 but with no output.
-TEST_F(BugreportTest, BugreportzVersionEmpty) {
- ExpectBugreportzVersion("");
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(-1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the main bugreportz command failed
-TEST_F(BugreportTest, BugreportzFailed) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(Return(666));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(666, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
-
-// Tests 'adb bugreport file.zip' when the bugreport could not be pulled
-TEST_F(BugreportTest, PullFails) {
- ExpectBugreportzVersion("1.1");
- EXPECT_CALL(br_, SendShellCommand(kTransportLocal, "HannibalLecter", "bugreportz -p", false, _))
- .WillOnce(DoAll(WithArg<4>(WriteOnStdout("OK:/device/bugreport.zip")),
- WithArg<4>(ReturnCallbackDone())));
- EXPECT_CALL(br_, DoSyncPull(ElementsAre(StrEq("/device/bugreport.zip")), StrEq("file.zip"),
- true, HasSubstr("file.zip")))
- .WillOnce(Return(false));
-
- const char* args[] = {"bugreport", "file.zip"};
- ASSERT_EQ(1, br_.DoIt(kTransportLocal, "HannibalLecter", 2, args));
-}
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 4ec0fc2..fb06bd9 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -32,7 +32,6 @@
#include "adb_auth.h"
#include "adb_listeners.h"
#include "adb_utils.h"
-#include "commandline.h"
#include "transport.h"
static std::string GetLogFilePath() {
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index a9185a0..d9a6c8c 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -54,11 +54,10 @@
#include "adb_io.h"
#include "adb_unique_fd.h"
#include "adb_utils.h"
-#include "bugreport.h"
-#include "commandline.h"
#include "file_sync_service.h"
#include "services.h"
#include "shell_service.h"
+#include "transport.h"
static int install_app(TransportType t, const char* serial, int argc, const char** argv);
static int install_multiple_app(TransportType t, const char* serial, int argc, const char** argv);
@@ -69,7 +68,8 @@
static auto& gProductOutPath = *new std::string();
extern int gListenAll;
-DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK(nullptr, nullptr);
+static constexpr char BUGZ_OK_PREFIX[] = "OK:";
+static constexpr char BUGZ_FAIL_PREFIX[] = "FAIL:";
static std::string product_file(const char *extra) {
if (gProductOutPath.empty()) {
@@ -84,7 +84,6 @@
static void help() {
fprintf(stderr, "%s\n", adb_version().c_str());
- // clang-format off
fprintf(stderr,
" -a - directs adb to listen on all interfaces for a connection\n"
" -d - directs command to the only connected USB device\n"
@@ -179,11 +178,9 @@
" (-g: grant all runtime permissions)\n"
" adb uninstall [-k] <package> - remove this app package from the device\n"
" ('-k' means keep the data and cache directories)\n"
- " adb bugreport [<path>] - return all information from the device that should be included in a zipped bug report.\n"
- " If <path> is a file, the bug report will be saved as that file.\n"
- " If <path> is a directory, the bug report will be saved in that directory with the name provided by the device.\n"
- " If <path> is omitted, the bug report will be saved in the current directory with the name provided by the device.\n"
- " NOTE: if the device does not support zipped bug reports, the bug report will be output on stdout.\n"
+ " adb bugreport [<zip_file>] - return all information from the device\n"
+ " that should be included in a bug report.\n"
+ "\n"
" adb backup [-f <file>] [-apk|-noapk] [-obb|-noobb] [-shared|-noshared] [-all] [-system|-nosystem] [<packages...>]\n"
" - write an archive of the device's data to <file>.\n"
" If no -f option is supplied then the data is written\n"
@@ -257,11 +254,11 @@
" ADB_TRACE - Print debug information. A comma separated list of the following values\n"
" 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n"
" ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n"
- " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n");
- // clang-format on
+ " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n"
+ );
}
-int usage() {
+static int usage() {
help();
return 1;
}
@@ -299,14 +296,17 @@
// this expects that incoming data will use the shell protocol, in which case
// stdout/stderr are routed independently and the remote exit code will be
// returned.
-// if |callback| is non-null, stdout/stderr output will be handled by it.
-int read_and_dump(int fd, bool use_shell_protocol = false,
- StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK) {
+// if |output| is non-null, stdout will be appended to it instead.
+// if |err| is non-null, stderr will be appended to it instead.
+static int read_and_dump(int fd, bool use_shell_protocol=false, std::string* output=nullptr,
+ std::string* err=nullptr) {
int exit_code = 0;
if (fd < 0) return exit_code;
std::unique_ptr<ShellProtocol> protocol;
int length = 0;
+ FILE* outfile = stdout;
+ std::string* outstring = output;
char raw_buffer[BUFSIZ];
char* buffer_ptr = raw_buffer;
@@ -324,13 +324,14 @@
if (!protocol->Read()) {
break;
}
- length = protocol->data_length();
switch (protocol->id()) {
case ShellProtocol::kIdStdout:
- callback->OnStdout(buffer_ptr, length);
+ outfile = stdout;
+ outstring = output;
break;
case ShellProtocol::kIdStderr:
- callback->OnStderr(buffer_ptr, length);
+ outfile = stderr;
+ outstring = err;
break;
case ShellProtocol::kIdExit:
exit_code = protocol->data()[0];
@@ -346,11 +347,17 @@
if (length <= 0) {
break;
}
- callback->OnStdout(buffer_ptr, length);
+ }
+
+ if (outstring == nullptr) {
+ fwrite(buffer_ptr, 1, length, outfile);
+ fflush(outfile);
+ } else {
+ outstring->append(buffer_ptr, length);
}
}
- return callback->Done(exit_code);
+ return exit_code;
}
static void read_status_line(int fd, char* buf, size_t count)
@@ -368,7 +375,19 @@
*buf = '\0';
}
-static void stdinout_raw_prologue(int inFd, int outFd, int& old_stdin_mode, int& old_stdout_mode) {
+static void copy_to_file(int inFd, int outFd) {
+ const size_t BUFSIZE = 32 * 1024;
+ char* buf = (char*) malloc(BUFSIZE);
+ if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
+ int len;
+ long total = 0;
+#ifdef _WIN32
+ int old_stdin_mode = -1;
+ int old_stdout_mode = -1;
+#endif
+
+ D("copy_to_file(%d -> %d)", inFd, outFd);
+
if (inFd == STDIN_FILENO) {
stdin_raw_init();
#ifdef _WIN32
@@ -387,39 +406,6 @@
}
}
#endif
-}
-
-static void stdinout_raw_epilogue(int inFd, int outFd, int old_stdin_mode, int old_stdout_mode) {
- if (inFd == STDIN_FILENO) {
- stdin_raw_restore();
-#ifdef _WIN32
- if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
- fatal_errno("could not restore stdin mode");
- }
-#endif
- }
-
-#ifdef _WIN32
- if (outFd == STDOUT_FILENO) {
- if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
- fatal_errno("could not restore stdout mode");
- }
- }
-#endif
-}
-
-static void copy_to_file(int inFd, int outFd) {
- const size_t BUFSIZE = 32 * 1024;
- char* buf = (char*) malloc(BUFSIZE);
- if (buf == nullptr) fatal("couldn't allocate buffer for copy_to_file");
- int len;
- long total = 0;
- int old_stdin_mode = -1;
- int old_stdout_mode = -1;
-
- D("copy_to_file(%d -> %d)", inFd, outFd);
-
- stdinout_raw_prologue(inFd, outFd, old_stdin_mode, old_stdout_mode);
while (true) {
if (inFd == STDIN_FILENO) {
@@ -444,7 +430,22 @@
total += len;
}
- stdinout_raw_epilogue(inFd, outFd, old_stdin_mode, old_stdout_mode);
+ if (inFd == STDIN_FILENO) {
+ stdin_raw_restore();
+#ifdef _WIN32
+ if (_setmode(STDIN_FILENO, old_stdin_mode) == -1) {
+ fatal_errno("could not restore stdin mode");
+ }
+#endif
+ }
+
+#ifdef _WIN32
+ if (outFd == STDOUT_FILENO) {
+ if (_setmode(STDOUT_FILENO, old_stdout_mode) == -1) {
+ fatal_errno("could not restore stdout mode");
+ }
+ }
+#endif
D("copy_to_file() finished after %lu bytes", total);
free(buf);
@@ -1116,16 +1117,20 @@
return true;
}
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
- bool disable_shell_protocol, StandardStreamsCallbackInterface* callback) {
+// Connects to the device "shell" service with |command| and prints the
+// resulting output.
+static int send_shell_command(TransportType transport_type, const char* serial,
+ const std::string& command,
+ bool disable_shell_protocol,
+ std::string* output=nullptr,
+ std::string* err=nullptr) {
int fd;
bool use_shell_protocol = false;
while (true) {
bool attempt_connection = true;
- // Use shell protocol if it's supported and the caller doesn't explicitly
- // disable it.
+ // Use shell protocol if it's supported and the caller doesn't explicitly disable it.
if (!disable_shell_protocol) {
FeatureSet features;
std::string error;
@@ -1147,13 +1152,13 @@
}
}
- fprintf(stderr, "- waiting for device -\n");
+ fprintf(stderr,"- waiting for device -\n");
if (!wait_for_device("wait-for-device", transport_type, serial)) {
return 1;
}
}
- int exit_code = read_and_dump(fd, use_shell_protocol, callback);
+ int exit_code = read_and_dump(fd, use_shell_protocol, output, err);
if (adb_close(fd) < 0) {
PLOG(ERROR) << "failure closing FD " << fd;
@@ -1162,6 +1167,45 @@
return exit_code;
}
+static int bugreport(TransportType transport_type, const char* serial, int argc,
+ const char** argv) {
+ if (argc == 1) return send_shell_command(transport_type, serial, "bugreport", false);
+ if (argc != 2) return usage();
+
+ // Zipped bugreport option - will call 'bugreportz', which prints the location of the generated
+ // file, then pull it to the destination file provided by the user.
+ std::string dest_file = argv[1];
+ if (!android::base::EndsWith(argv[1], ".zip")) {
+ // TODO: use a case-insensitive comparison (like EndsWithIgnoreCase
+ dest_file += ".zip";
+ }
+ std::string output;
+
+ fprintf(stderr, "Bugreport is in progress and it could take minutes to complete.\n"
+ "Please be patient and do not cancel or disconnect your device until it completes.\n");
+ int status = send_shell_command(transport_type, serial, "bugreportz", false, &output, nullptr);
+ if (status != 0 || output.empty()) return status;
+ output = android::base::Trim(output);
+
+ if (android::base::StartsWith(output, BUGZ_OK_PREFIX)) {
+ const char* zip_file = &output[strlen(BUGZ_OK_PREFIX)];
+ std::vector<const char*> srcs{zip_file};
+ status = do_sync_pull(srcs, dest_file.c_str(), true, dest_file.c_str()) ? 0 : 1;
+ if (status != 0) {
+ fprintf(stderr, "Could not copy file '%s' to '%s'\n", zip_file, dest_file.c_str());
+ }
+ return status;
+ }
+ if (android::base::StartsWith(output, BUGZ_FAIL_PREFIX)) {
+ const char* error_message = &output[strlen(BUGZ_FAIL_PREFIX)];
+ fprintf(stderr, "Device failed to take a zipped bugreport: %s\n", error_message);
+ return -1;
+ }
+ fprintf(stderr, "Unexpected string (%s) returned by bugreportz, "
+ "device probably does not support -z option\n", output.c_str());
+ return -1;
+}
+
static int logcat(TransportType transport, const char* serial, int argc, const char** argv) {
char* log_tags = getenv("ANDROID_LOG_TAGS");
std::string quoted = escape_arg(log_tags == nullptr ? "" : log_tags);
@@ -1182,29 +1226,6 @@
return send_shell_command(transport, serial, cmd, true);
}
-static void write_zeros(int bytes, int fd) {
- int old_stdin_mode = -1;
- int old_stdout_mode = -1;
- char* buf = (char*) calloc(1, bytes);
- if (buf == nullptr) fatal("couldn't allocate buffer for write_zeros");
-
- D("write_zeros(%d) -> %d", bytes, fd);
-
- stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
-
- if (fd == STDOUT_FILENO) {
- fwrite(buf, 1, bytes, stdout);
- fflush(stdout);
- } else {
- adb_write(fd, buf, bytes);
- }
-
- stdinout_raw_prologue(-1, fd, old_stdin_mode, old_stdout_mode);
-
- D("write_zeros() finished");
- free(buf);
-}
-
static int backup(int argc, const char** argv) {
const char* filename = "backup.ab";
@@ -1285,9 +1306,6 @@
printf("Now unlock your device and confirm the restore operation.\n");
copy_to_file(tarFd, fd);
- // Provide an in-band EOD marker in case the archive file is malformed
- write_zeros(512*2, fd);
-
// Wait until the other side finishes, or it'll get sent SIGHUP.
copy_to_file(fd, STDOUT_FILENO);
@@ -1323,7 +1341,7 @@
if (hint.find_first_of(OS_PATH_SEPARATORS) != std::string::npos) { // NOLINT
std::string cwd;
if (!getcwd(&cwd)) {
- perror("adb: getcwd failed");
+ fprintf(stderr, "adb: getcwd failed: %s\n", strerror(errno));
return "";
}
return android::base::StringPrintf("%s%c%s", cwd.c_str(), OS_PATH_SEPARATOR, hint.c_str());
@@ -1423,16 +1441,6 @@
#endif
}
-static bool _use_legacy_install() {
- FeatureSet features;
- std::string error;
- if (!adb_get_feature_set(&features, &error)) {
- fprintf(stderr, "error: %s\n", error.c_str());
- return true;
- }
- return !CanUseFeature(features, kFeatureCmd);
-}
-
int adb_commandline(int argc, const char **argv) {
int no_daemon = 0;
int is_daemon = 0;
@@ -1754,8 +1762,7 @@
} else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
return adb_root(argv[0]) ? 0 : 1;
} else if (!strcmp(argv[0], "bugreport")) {
- Bugreport bugreport;
- return bugreport.DoIt(transport_type, serial, argc, argv);
+ return bugreport(transport_type, serial, argc, argv);
} else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
bool reverse = !strcmp(argv[0], "reverse");
++argv;
@@ -1849,10 +1856,17 @@
}
else if (!strcmp(argv[0], "install")) {
if (argc < 2) return usage();
- if (_use_legacy_install()) {
- return install_app_legacy(transport_type, serial, argc, argv);
+ FeatureSet features;
+ std::string error;
+ if (!adb_get_feature_set(&features, &error)) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return 1;
}
- return install_app(transport_type, serial, argc, argv);
+
+ if (CanUseFeature(features, kFeatureCmd)) {
+ return install_app(transport_type, serial, argc, argv);
+ }
+ return install_app_legacy(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "install-multiple")) {
if (argc < 2) return usage();
@@ -1860,10 +1874,17 @@
}
else if (!strcmp(argv[0], "uninstall")) {
if (argc < 2) return usage();
- if (_use_legacy_install()) {
- return uninstall_app_legacy(transport_type, serial, argc, argv);
+ FeatureSet features;
+ std::string error;
+ if (!adb_get_feature_set(&features, &error)) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return 1;
}
- return uninstall_app(transport_type, serial, argc, argv);
+
+ if (CanUseFeature(features, kFeatureCmd)) {
+ return uninstall_app(transport_type, serial, argc, argv);
+ }
+ return uninstall_app_legacy(transport_type, serial, argc, argv);
}
else if (!strcmp(argv[0], "sync")) {
std::string src;
@@ -2077,6 +2098,7 @@
int i;
struct stat sb;
uint64_t total_size = 0;
+
// Find all APK arguments starting at end.
// All other arguments passed through verbatim.
int first_apk = -1;
@@ -2101,14 +2123,7 @@
return 1;
}
- std::string install_cmd;
- if (_use_legacy_install()) {
- install_cmd = "exec:pm";
- } else {
- install_cmd = "exec:cmd package";
- }
-
- std::string cmd = android::base::StringPrintf("%s install-create -S %" PRIu64, install_cmd.c_str(), total_size);
+ std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
for (i = 1; i < first_apk; i++) {
cmd += " " + escape_arg(argv[i]);
}
@@ -2150,8 +2165,8 @@
}
std::string cmd = android::base::StringPrintf(
- "%s install-write -S %" PRIu64 " %d %d_%s -",
- install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
+ "exec:pm install-write -S %" PRIu64 " %d %d_%s -",
+ static_cast<uint64_t>(sb.st_size), session_id, i, adb_basename(file).c_str());
int localFd = adb_open(file, O_RDONLY);
if (localFd < 0) {
@@ -2186,8 +2201,8 @@
finalize_session:
// Commit session if we streamed everything okay; otherwise abandon
std::string service =
- android::base::StringPrintf("%s install-%s %d",
- install_cmd.c_str(), success ? "commit" : "abandon", session_id);
+ android::base::StringPrintf("exec:pm install-%s %d",
+ success ? "commit" : "abandon", session_id);
fd = adb_connect(service, &error);
if (fd < 0) {
fprintf(stderr, "Connect error for finalize: %s\n", error.c_str());
diff --git a/adb/commandline.h b/adb/commandline.h
deleted file mode 100644
index 0cf655c..0000000
--- a/adb/commandline.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COMMANDLINE_H
-#define COMMANDLINE_H
-
-#include "adb.h"
-
-// Callback used to handle the standard streams (stdout and stderr) sent by the
-// device's upon receiving a command.
-//
-class StandardStreamsCallbackInterface {
- public:
- StandardStreamsCallbackInterface() {
- }
- // Handles the stdout output from devices supporting the Shell protocol.
- virtual void OnStdout(const char* buffer, int length) = 0;
-
- // Handles the stderr output from devices supporting the Shell protocol.
- virtual void OnStderr(const char* buffer, int length) = 0;
-
- // Indicates the communication is finished and returns the appropriate error
- // code.
- //
- // |status| has the status code returning by the underlying communication
- // channels
- virtual int Done(int status) = 0;
-
- protected:
- static void OnStream(std::string* string, FILE* stream, const char* buffer, int length) {
- if (string != nullptr) {
- string->append(buffer, length);
- } else {
- fwrite(buffer, 1, length, stream);
- fflush(stream);
- }
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface);
-};
-
-// Default implementation that redirects the streams to the equilavent host
-// stream or to a string
-// passed to the constructor.
-class DefaultStandardStreamsCallback : public StandardStreamsCallbackInterface {
- public:
- // If |stdout_str| is non-null, OnStdout will append to it.
- // If |stderr_str| is non-null, OnStderr will append to it.
- DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
- : stdout_str_(stdout_str), stderr_str_(stderr_str) {
- }
-
- void OnStdout(const char* buffer, int length) {
- OnStream(stdout_str_, stdout, buffer, length);
- }
-
- void OnStderr(const char* buffer, int length) {
- OnStream(stderr_str_, stderr, buffer, length);
- }
-
- int Done(int status) {
- return status;
- }
-
- private:
- std::string* stdout_str_;
- std::string* stderr_str_;
-
- DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
-};
-
-// Singleton.
-extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
-
-int adb_commandline(int argc, const char** argv);
-int usage();
-
-// Connects to the device "shell" service with |command| and prints the
-// resulting output.
-// if |callback| is non-null, stdout/stderr output will be handled by it.
-int send_shell_command(TransportType transport_type, const char* serial, const std::string& command,
- bool disable_shell_protocol, StandardStreamsCallbackInterface* callback =
- &DEFAULT_STANDARD_STREAMS_CALLBACK);
-
-#endif // COMMANDLINE_H
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index b54243e..094988a 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -29,11 +29,11 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <libminijail.h>
#include <scoped_minijail.h>
-#include "cutils/properties.h"
#include "debuggerd/client.h"
#include "private/android_filesystem_config.h"
#include "selinux/android.h"
@@ -48,9 +48,7 @@
static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
#if defined(ALLOW_ADBD_ROOT)
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.debuggable", value, "");
- if (strcmp(value, "1") == 0) {
+ if (android::base::GetBoolProperty("ro.debuggable", false)) {
return;
}
#endif
@@ -59,8 +57,6 @@
static bool should_drop_privileges() {
#if defined(ALLOW_ADBD_ROOT)
- char value[PROPERTY_VALUE_MAX];
-
// The properties that affect `adb root` and `adb unroot` are ro.secure and
// ro.debuggable. In this context the names don't make the expected behavior
// particularly obvious.
@@ -71,24 +67,19 @@
//
// ro.secure:
// Drop privileges by default. Set to 1 on userdebug and user builds.
- property_get("ro.secure", value, "1");
- bool ro_secure = (strcmp(value, "1") == 0);
-
- property_get("ro.debuggable", value, "");
- bool ro_debuggable = (strcmp(value, "1") == 0);
+ bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
+ bool ro_debuggable = android::base::GetBoolProperty("ro.debuggable", false);
// Drop privileges if ro.secure is set...
bool drop = ro_secure;
- property_get("service.adb.root", value, "");
- bool adb_root = (strcmp(value, "1") == 0);
- bool adb_unroot = (strcmp(value, "0") == 0);
-
// ... except "adb root" lets you keep privileges in a debuggable build.
+ std::string prop = android::base::GetProperty("service.adb.root", "");
+ bool adb_root = (prop == "1");
+ bool adb_unroot = (prop == "0");
if (ro_debuggable && adb_root) {
drop = false;
}
-
// ... and "adb unroot" lets you explicitly drop privileges.
if (adb_unroot) {
drop = true;
@@ -159,7 +150,7 @@
// descriptor will always be open.
adbd_cloexec_auth_socket();
- if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) {
+ if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
auth_required = false;
}
@@ -187,14 +178,13 @@
// If one of these properties is set, also listen on that port.
// If one of the properties isn't set and we couldn't listen on usb, listen
// on the default port.
- char prop_port[PROPERTY_VALUE_MAX];
- property_get("service.adb.tcp.port", prop_port, "");
- if (prop_port[0] == '\0') {
- property_get("persist.adb.tcp.port", prop_port, "");
+ std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
+ if (prop_port.empty()) {
+ prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
}
int port;
- if (sscanf(prop_port, "%d", &port) == 1 && port > 0) {
+ if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
D("using port=%d", port);
// Listen on TCP port specified by service.adb.tcp.port property.
local_init(port);
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 8f1c9b0..5ca73cc 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -29,10 +29,11 @@
#include <string>
+#include <android-base/properties.h>
+
#include "adb.h"
#include "adb_io.h"
#include "adb_utils.h"
-#include "cutils/properties.h"
#include "fs_mgr.h"
// Returns the device used to mount a directory in /proc/mounts.
@@ -53,10 +54,7 @@
// Returns the device used to mount a directory in the fstab.
static std::string find_fstab_mount(const char* dir) {
- char propbuf[PROPERTY_VALUE_MAX];
-
- property_get("ro.hardware", propbuf, "");
- std::string fstab_filename = std::string("/fstab.") + propbuf;
+ std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
struct fstab* fstab = fs_mgr_read_fstab(fstab_filename.c_str());
struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, dir);
std::string dev = rec ? std::string(rec->blk_device) : "";
@@ -113,12 +111,8 @@
return;
}
- char prop_buf[PROPERTY_VALUE_MAX];
- property_get("partition.system.verified", prop_buf, "");
- bool system_verified = (strlen(prop_buf) > 0);
-
- property_get("partition.vendor.verified", prop_buf, "");
- bool vendor_verified = (strlen(prop_buf) > 0);
+ bool system_verified = !(android::base::GetProperty("partition.system.verified", "").empty());
+ bool vendor_verified = !(android::base::GetProperty("partition.vendor.verified", "").empty());
if (system_verified || vendor_verified) {
// Allow remount but warn of likely bad effects
@@ -136,9 +130,7 @@
}
bool success = true;
- property_get("ro.build.system_root_image", prop_buf, "");
- bool system_root = !strcmp(prop_buf, "true");
- if (system_root) {
+ if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
success &= remount_partition(fd, "/");
} else {
success &= remount_partition(fd, "/system");
diff --git a/adb/services.cpp b/adb/services.cpp
index 2207a3e..0c3dd00 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -39,7 +39,7 @@
#if !ADB_HOST
#include "cutils/android_reboot.h"
-#include "cutils/properties.h"
+#include <android-base/properties.h>
#endif
#include "adb.h"
@@ -73,15 +73,13 @@
WriteFdExactly(fd, "adbd is already running as root\n");
adb_close(fd);
} else {
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.debuggable", value, "");
- if (strcmp(value, "1") != 0) {
+ if (!android::base::GetBoolProperty("ro.debuggable", false)) {
WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
adb_close(fd);
return;
}
- property_set("service.adb.root", "1");
+ android::base::SetProperty("service.adb.root", "1");
WriteFdExactly(fd, "restarting adbd as root\n");
adb_close(fd);
}
@@ -92,7 +90,7 @@
WriteFdExactly(fd, "adbd not running as root\n");
adb_close(fd);
} else {
- property_set("service.adb.root", "0");
+ android::base::SetProperty("service.adb.root", "0");
WriteFdExactly(fd, "restarting adbd as non root\n");
adb_close(fd);
}
@@ -106,15 +104,13 @@
return;
}
- char value[PROPERTY_VALUE_MAX];
- snprintf(value, sizeof(value), "%d", port);
- property_set("service.adb.tcp.port", value);
+ android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
WriteFdFmt(fd, "restarting in TCP mode port: %d\n", port);
adb_close(fd);
}
void restart_usb_service(int fd, void *cookie) {
- property_set("service.adb.tcp.port", "0");
+ android::base::SetProperty("service.adb.tcp.port", "0");
WriteFdExactly(fd, "restarting in USB mode\n");
adb_close(fd);
}
@@ -155,16 +151,9 @@
sync();
- char property_val[PROPERTY_VALUE_MAX];
- int ret = snprintf(property_val, sizeof(property_val), "reboot,%s", reboot_arg);
- if (ret >= static_cast<int>(sizeof(property_val))) {
- WriteFdFmt(fd, "reboot string too long: %d\n", ret);
- return false;
- }
-
- ret = property_set(ANDROID_RB_PROPERTY, property_val);
- if (ret < 0) {
- WriteFdFmt(fd, "reboot failed: %d\n", ret);
+ std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg);
+ if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
+ WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str());
return false;
}
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index f5188e9..ae628e4 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -24,16 +24,17 @@
#include <stdio.h>
#include <sys/stat.h>
-#include "cutils/properties.h"
+#include "android-base/properties.h"
+#include "android-base/stringprintf.h"
#include "adb.h"
#include "adb_io.h"
+#include "adb_unique_fd.h"
#include "fs_mgr.h"
#include "remount_service.h"
#include "fec/io.h"
-#define FSTAB_PREFIX "/fstab."
struct fstab *fstab;
#ifdef ALLOW_ADBD_DISABLE_VERITY
@@ -88,56 +89,46 @@
return 0;
}
-void set_verity_enabled_state_service(int fd, void* cookie)
-{
+void set_verity_enabled_state_service(int fd, void* cookie) {
+ unique_fd closer(fd);
+
bool enable = (cookie != NULL);
- if (kAllowDisableVerity) {
- char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
- char propbuf[PROPERTY_VALUE_MAX];
- int i;
- bool any_changed = false;
-
- property_get("ro.secure", propbuf, "0");
- if (strcmp(propbuf, "1")) {
- WriteFdFmt(fd, "verity not enabled - ENG build\n");
- goto errout;
- }
-
- property_get("ro.debuggable", propbuf, "0");
- if (strcmp(propbuf, "1")) {
- WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
- goto errout;
- }
-
- property_get("ro.hardware", propbuf, "");
- snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s",
- propbuf);
-
- fstab = fs_mgr_read_fstab(fstab_filename);
- if (!fstab) {
- WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename);
- goto errout;
- }
-
- /* Loop through entries looking for ones that vold manages */
- for (i = 0; i < fstab->num_entries; i++) {
- if(fs_mgr_is_verified(&fstab->recs[i])) {
- if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
- fstab->recs[i].mount_point,
- enable)) {
- any_changed = true;
- }
- }
- }
-
- if (any_changed) {
- WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
- }
- } else {
+ if (!kAllowDisableVerity) {
WriteFdFmt(fd, "%s-verity only works for userdebug builds\n",
enable ? "enable" : "disable");
}
-errout:
- adb_close(fd);
+ if (!android::base::GetBoolProperty("ro.secure", false)) {
+ WriteFdFmt(fd, "verity not enabled - ENG build\n");
+ return;
+ }
+
+ if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+ WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
+ return;
+ }
+
+ std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
+
+ fstab = fs_mgr_read_fstab(fstab_filename.c_str());
+ if (!fstab) {
+ WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename.c_str());
+ return;
+ }
+
+ // Loop through entries looking for ones that vold manages.
+ bool any_changed = false;
+ for (int i = 0; i < fstab->num_entries; i++) {
+ if (fs_mgr_is_verified(&fstab->recs[i])) {
+ if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+ fstab->recs[i].mount_point,
+ enable)) {
+ any_changed = true;
+ }
+ }
+ }
+
+ if (any_changed) {
+ WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
+ }
}
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index abba745..503e018 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -31,7 +31,7 @@
#include <vector>
#if !ADB_HOST
-#include "cutils/properties.h"
+#include <android-base/properties.h>
#endif
#include "adb.h"
@@ -416,12 +416,12 @@
D("LS(%d): bound to '%s' via %d", s->id, name, fd);
#if !ADB_HOST
- char debug[PROPERTY_VALUE_MAX];
+ bool debuggable = false;
if (!strncmp(name, "root:", 5)) {
- property_get("ro.debuggable", debug, "");
+ debuggable = android::base::GetBoolProperty("ro.debuggable", false);
}
- if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0) ||
+ if ((!strncmp(name, "root:", 5) && getuid() != 0 && debuggable) ||
(!strncmp(name, "unroot:", 7) && getuid() == 0) ||
!strncmp(name, "usb:", 4) ||
!strncmp(name, "tcpip:", 6)) {
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index f895943..a94b41e 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -33,7 +33,7 @@
#include <cutils/sockets.h>
#if !ADB_HOST
-#include "cutils/properties.h"
+#include <android-base/properties.h>
#endif
#include "adb.h"
@@ -356,15 +356,13 @@
func = client_socket_thread;
debug_name = "client";
#else
- /* For the adbd daemon in the system image we need to distinguish
- * between the device, and the emulator. */
- char is_qemu[PROPERTY_VALUE_MAX];
- property_get("ro.kernel.qemu", is_qemu, "");
- if (!strcmp(is_qemu, "1")) {
- /* Running inside the emulator: use QEMUD pipe as the transport. */
+ // For the adbd daemon in the system image we need to distinguish
+ // between the device, and the emulator.
+ if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
+ // Running inside the emulator: use QEMUD pipe as the transport.
func = qemu_socket_thread;
} else {
- /* Running inside the device: use TCP socket as the transport. */
+ // Running inside the device: use TCP socket as the transport.
func = server_socket_thread;
}
debug_name = "server";
diff --git a/adb/usb_linux_client.cpp b/adb/usb_linux_client.cpp
index 1b05439..6de10f5 100644
--- a/adb/usb_linux_client.cpp
+++ b/adb/usb_linux_client.cpp
@@ -18,7 +18,6 @@
#include "sysdeps.h"
-#include <cutils/properties.h>
#include <dirent.h>
#include <errno.h>
#include <linux/usb/ch9.h>
@@ -36,6 +35,7 @@
#include <mutex>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include "adb.h"
#include "transport.h"
@@ -478,7 +478,7 @@
}
adb_sleep_ms(1000);
}
- property_set("sys.usb.ffs.ready", "1");
+ android::base::SetProperty("sys.usb.ffs.ready", "1");
D("[ usb_thread - registering device ]");
register_usb_transport(usb, 0, 0, 1);
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 987ba83..d6b631f 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -402,6 +402,9 @@
" --skip-secondary Will not flash secondary slots when\n"
" performing a flashall or update. This\n"
" will preserve data on other slots.\n"
+ " --skip-reboot Will not reboot the device when\n"
+ " performing commands that normally\n"
+ " trigger a reboot.\n"
#if !defined(_WIN32)
" --wipe-and-use-fbe On devices which support it,\n"
" erase userdata and cache, and\n"
@@ -1392,6 +1395,7 @@
bool wants_wipe = false;
bool wants_reboot = false;
bool wants_reboot_bootloader = false;
+ bool skip_reboot = false;
bool wants_set_active = false;
bool skip_secondary = false;
bool erase_first = true;
@@ -1419,6 +1423,7 @@
{"set_active", optional_argument, 0, 'a'},
{"set-active", optional_argument, 0, 'a'},
{"skip-secondary", no_argument, 0, 0},
+ {"skip-reboot", no_argument, 0, 0},
#if !defined(_WIN32)
{"wipe-and-use-fbe", no_argument, 0, 0},
#endif
@@ -1505,6 +1510,8 @@
slot_override = std::string(optarg);
} else if (strcmp("skip-secondary", longopts[longindex].name) == 0 ) {
skip_secondary = true;
+ } else if (strcmp("skip-reboot", longopts[longindex].name) == 0 ) {
+ skip_reboot = true;
#if !defined(_WIN32)
} else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
wants_wipe = true;
@@ -1729,7 +1736,7 @@
do_update(transport, "update.zip", slot_override, erase_first, skip_secondary || slot_all);
skip(1);
}
- wants_reboot = 1;
+ wants_reboot = true;
} else if(!strcmp(*argv, "set_active")) {
require(2);
std::string slot = verify_slot(transport, std::string(argv[1]), false);
@@ -1784,7 +1791,7 @@
if (wants_set_active) {
fb_set_active(next_active.c_str());
}
- if (wants_reboot) {
+ if (wants_reboot && !skip_reboot) {
fb_queue_reboot();
fb_queue_wait_for_disconnect();
} else if (wants_reboot_bootloader) {