Merge "Nativeloader: Restrict anonymous namespace creation" into qt-dev
diff --git a/adb/adb.cpp b/adb/adb.cpp
index e417f05..2dd22b3 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -280,6 +280,9 @@
} else if (type == "sideload") {
D("setting connection_state to kCsSideload");
t->SetConnectionState(kCsSideload);
+ } else if (type == "rescue") {
+ D("setting connection_state to kCsRescue");
+ t->SetConnectionState(kCsRescue);
} else {
D("setting connection_state to kCsHost");
t->SetConnectionState(kCsHost);
diff --git a/adb/adb.h b/adb/adb.h
index c60dcbc..3a6f059 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -107,6 +107,7 @@
kCsHost,
kCsRecovery,
kCsSideload,
+ kCsRescue,
};
inline bool ConnectionStateIsOnline(ConnectionState state) {
@@ -116,6 +117,7 @@
case kCsHost:
case kCsRecovery:
case kCsSideload:
+ case kCsRescue:
return true;
default:
return false;
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 43a3e5e..552df41 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -190,7 +190,7 @@
"scripting:\n"
" wait-for[-TRANSPORT]-STATE\n"
" wait for device to be in the given state\n"
- " STATE: device, recovery, sideload, bootloader, or disconnect\n"
+ " STATE: device, recovery, rescue, sideload, bootloader, or disconnect\n"
" TRANSPORT: usb, local, or any [default=any]\n"
" get-state print offline | bootloader | device\n"
" get-serialno print <serial-number>\n"
@@ -838,26 +838,25 @@
#define SIDELOAD_HOST_BLOCK_SIZE (CHUNK_SIZE)
-/*
- * The sideload-host protocol serves the data in a file (given on the
- * command line) to the client, using a simple protocol:
- *
- * - The connect message includes the total number of bytes in the
- * file and a block size chosen by us.
- *
- * - The other side sends the desired block number as eight decimal
- * digits (eg "00000023" for block 23). Blocks are numbered from
- * zero.
- *
- * - We send back the data of the requested block. The last block is
- * likely to be partial; when the last block is requested we only
- * send the part of the block that exists, it's not padded up to the
- * block size.
- *
- * - When the other side sends "DONEDONE" instead of a block number,
- * we hang up.
- */
-static int adb_sideload_host(const char* filename) {
+// Connects to the sideload / rescue service on the device (served by minadbd) and sends over the
+// data in an OTA package.
+//
+// It uses a simple protocol as follows.
+//
+// - The connect message includes the total number of bytes in the file and a block size chosen by
+// us.
+//
+// - The other side sends the desired block number as eight decimal digits (e.g. "00000023" for
+// block 23). Blocks are numbered from zero.
+//
+// - We send back the data of the requested block. The last block is likely to be partial; when the
+// last block is requested we only send the part of the block that exists, it's not padded up to
+// the block size.
+//
+// - When the other side sends "DONEDONE" or "FAILFAIL" instead of a block number, we have done all
+// the data transfer.
+//
+static int adb_sideload_install(const char* filename, bool rescue_mode) {
// TODO: use a LinePrinter instead...
struct stat sb;
if (stat(filename, &sb) == -1) {
@@ -870,14 +869,18 @@
return -1;
}
- std::string service =
- android::base::StringPrintf("sideload-host:%" PRId64 ":%d",
- static_cast<int64_t>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
+ std::string service = android::base::StringPrintf(
+ "%s:%" PRId64 ":%d", rescue_mode ? "rescue-install" : "sideload-host",
+ static_cast<int64_t>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
std::string error;
unique_fd device_fd(adb_connect(service, &error));
if (device_fd < 0) {
fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
+ if (rescue_mode) {
+ return -1;
+ }
+
// If this is a small enough package, maybe this is an older device that doesn't
// support sideload-host. Try falling back to the older (<= K) sideload method.
if (sb.st_size > INT_MAX) {
@@ -901,10 +904,14 @@
}
buf[8] = '\0';
- if (strcmp("DONEDONE", buf) == 0) {
+ if (strcmp(kSideloadServiceExitSuccess, buf) == 0 ||
+ strcmp(kSideloadServiceExitFailure, buf) == 0) {
printf("\rTotal xfer: %.2fx%*s\n",
static_cast<double>(xfer) / (sb.st_size ? sb.st_size : 1),
static_cast<int>(strlen(filename) + 10), "");
+ if (strcmp(kSideloadServiceExitFailure, buf) == 0) {
+ return 1;
+ }
return 0;
}
@@ -1037,11 +1044,12 @@
}
if (components[3] != "any" && components[3] != "bootloader" && components[3] != "device" &&
- components[3] != "recovery" && components[3] != "sideload" &&
+ components[3] != "recovery" && components[3] != "rescue" && components[3] != "sideload" &&
components[3] != "disconnect") {
fprintf(stderr,
"adb: unknown state %s; "
- "expected 'any', 'bootloader', 'device', 'recovery', 'sideload', or 'disconnect'\n",
+ "expected 'any', 'bootloader', 'device', 'recovery', 'rescue', 'sideload', or "
+ "'disconnect'\n",
components[3].c_str());
return false;
}
@@ -1627,11 +1635,25 @@
return adb_kill_server() ? 0 : 1;
} else if (!strcmp(argv[0], "sideload")) {
if (argc != 2) error_exit("sideload requires an argument");
- if (adb_sideload_host(argv[1])) {
+ if (adb_sideload_install(argv[1], false /* rescue_mode */)) {
return 1;
} else {
return 0;
}
+ } else if (!strcmp(argv[0], "rescue")) {
+ // adb rescue getprop <prop>
+ // adb rescue install <filename>
+ if (argc != 3) error_exit("rescue requires two arguments");
+ if (!strcmp(argv[1], "getprop")) {
+ return adb_connect_command(android::base::StringPrintf("rescue-getprop:%s", argv[2]));
+ } else if (!strcmp(argv[1], "install")) {
+ if (adb_sideload_install(argv[2], true /* rescue_mode */) != 0) {
+ return 1;
+ }
+ } else {
+ error_exit("invalid rescue argument");
+ }
+ return 0;
} else if (!strcmp(argv[0], "tcpip")) {
if (argc != 2) error_exit("tcpip requires an argument");
int port;
diff --git a/adb/services.cpp b/adb/services.cpp
index cf346ba..335ffc4 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -227,6 +227,8 @@
sinfo->state = kCsDevice;
} else if (name == "-recovery") {
sinfo->state = kCsRecovery;
+ } else if (name == "-rescue") {
+ sinfo->state = kCsRescue;
} else if (name == "-sideload") {
sinfo->state = kCsSideload;
} else if (name == "-bootloader") {
diff --git a/adb/services.h b/adb/services.h
index 0ce25ba..8f3919b 100644
--- a/adb/services.h
+++ b/adb/services.h
@@ -23,5 +23,9 @@
constexpr char kShellServiceArgPty[] = "pty";
constexpr char kShellServiceArgShellProtocol[] = "v2";
+// Special flags sent by minadbd that indicate the end of sideload transfer and install result.
+constexpr char kSideloadServiceExitSuccess[] = "DONEDONE";
+constexpr char kSideloadServiceExitFailure[] = "FAILFAIL";
+
unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func);
#endif // SERVICES_H_
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 15c3a9a..841865a 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -1012,6 +1012,8 @@
return "host";
case kCsRecovery:
return "recovery";
+ case kCsRescue:
+ return "rescue";
case kCsNoPerm:
return UsbNoPermissionsShortHelpText();
case kCsSideload: