summaryrefslogtreecommitdiffstats
path: root/minadbd
diff options
context:
space:
mode:
authorTianjie Xu <xunchang@google.com>2019-04-12 01:42:25 +0200
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-04-12 01:42:25 +0200
commit6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e (patch)
treefc51bb568fdb244bd4cc7687a665230a1f3a9fa4 /minadbd
parentMerge "Build libinstall as a static library." (diff)
parentAdd socket communication between recovery and minadbd (diff)
downloadandroid_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar.gz
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar.bz2
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar.lz
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar.xz
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.tar.zst
android_bootable_recovery-6c5f70b9b2ed9233b6b7db11c96c331e5927bf4e.zip
Diffstat (limited to 'minadbd')
-rw-r--r--minadbd/Android.bp31
-rw-r--r--minadbd/minadbd.cpp48
-rw-r--r--minadbd/minadbd_services.cpp73
-rw-r--r--minadbd/minadbd_services.h (renamed from minadbd/minadbd.h)7
-rw-r--r--minadbd/minadbd_types.h53
5 files changed, 187 insertions, 25 deletions
diff --git a/minadbd/Android.bp b/minadbd/Android.bp
index 9b889f4a2..e4f7712e5 100644
--- a/minadbd/Android.bp
+++ b/minadbd/Android.bp
@@ -40,7 +40,6 @@ cc_library {
srcs: [
"fuse_adb_provider.cpp",
- "minadbd.cpp",
"minadbd_services.cpp",
],
@@ -52,6 +51,36 @@ cc_library {
],
}
+cc_library_headers {
+ name: "libminadbd_headers",
+ recovery_available: true,
+ // TODO create a include dir
+ export_include_dirs: [
+ ".",
+ ],
+}
+
+cc_binary {
+ name: "minadbd",
+ recovery: true,
+
+ defaults: [
+ "minadbd_defaults",
+ ],
+
+ srcs: [
+ "minadbd.cpp",
+ ],
+
+ shared_libs: [
+ "libadbd",
+ "libbase",
+ "libcrypto",
+ "libfusesideload",
+ "libminadbd_services",
+ ],
+}
+
cc_test {
name: "minadbd_test",
isolated: true,
diff --git a/minadbd/minadbd.cpp b/minadbd/minadbd.cpp
index 349189cc7..57158ad57 100644
--- a/minadbd/minadbd.cpp
+++ b/minadbd/minadbd.cpp
@@ -14,30 +14,54 @@
* limitations under the License.
*/
-#include "minadbd.h"
-
#include <errno.h>
+#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <strings.h>
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include "adb.h"
#include "adb_auth.h"
#include "transport.h"
-int minadbd_main() {
- adb_device_banner = "sideload";
+#include "minadbd_services.h"
+#include "minadbd_types.h"
+
+int main(int argc, char** argv) {
+ android::base::InitLogging(argv, &android::base::StderrLogger);
+ // TODO(xunchang) implement a command parser
+ if (argc != 3 || strcmp("--socket_fd", argv[1]) != 0) {
+ LOG(ERROR) << "minadbd has invalid arguments, argc: " << argc;
+ exit(kMinadbdArgumentsParsingError);
+ }
+
+ int socket_fd;
+ if (!android::base::ParseInt(argv[2], &socket_fd)) {
+ LOG(ERROR) << "Failed to parse int in " << argv[2];
+ exit(kMinadbdArgumentsParsingError);
+ }
+ if (fcntl(socket_fd, F_GETFD, 0) == -1) {
+ PLOG(ERROR) << "Failed to get minadbd socket";
+ exit(kMinadbdSocketIOError);
+ }
+ SetMinadbdSocketFd(socket_fd);
+
+ adb_device_banner = "sideload";
- signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
- // We can't require authentication for sideloading. http://b/22025550.
- auth_required = false;
+ // We can't require authentication for sideloading. http://b/22025550.
+ auth_required = false;
- init_transport_registration();
- usb_init();
+ init_transport_registration();
+ usb_init();
- VLOG(ADB) << "Event loop starting";
- fdevent_loop();
+ VLOG(ADB) << "Event loop starting";
+ fdevent_loop();
- return 0;
+ return 0;
}
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp
index 6fe5c79bc..79e6fc4e0 100644
--- a/minadbd/minadbd_services.cpp
+++ b/minadbd/minadbd_services.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "minadbd_services.h"
+
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
@@ -27,38 +29,95 @@
#include <string_view>
#include <thread>
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/memory.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
#include "adb.h"
#include "adb_unique_fd.h"
#include "fdevent.h"
#include "fuse_adb_provider.h"
#include "fuse_sideload.h"
+#include "minadbd_types.h"
#include "services.h"
#include "sysdeps.h"
+static int minadbd_socket = -1;
+void SetMinadbdSocketFd(int socket_fd) {
+ minadbd_socket = socket_fd;
+}
+
+static bool WriteCommandToFd(MinadbdCommands cmd, int fd) {
+ char message[kMinadbdMessageSize];
+ memcpy(message, kMinadbdCommandPrefix, strlen(kMinadbdStatusPrefix));
+ android::base::put_unaligned(message + strlen(kMinadbdStatusPrefix), cmd);
+
+ if (!android::base::WriteFully(fd, message, kMinadbdMessageSize)) {
+ PLOG(ERROR) << "Failed to write message " << message;
+ return false;
+ }
+ return true;
+}
+
+// Blocks and reads the command status from |fd|. Returns false if the received message has a
+// format error.
+static bool WaitForCommandStatus(int fd, MinadbdCommandStatus* status) {
+ char buffer[kMinadbdMessageSize];
+ if (!android::base::ReadFully(fd, buffer, kMinadbdMessageSize)) {
+ PLOG(ERROR) << "Failed to response status from socket";
+ exit(kMinadbdSocketIOError);
+ }
+
+ std::string message(buffer, buffer + kMinadbdMessageSize);
+ if (!android::base::StartsWith(message, kMinadbdStatusPrefix)) {
+ LOG(ERROR) << "Failed to parse status in " << message;
+ return false;
+ }
+
+ *status = android::base::get_unaligned<MinadbdCommandStatus>(
+ message.substr(strlen(kMinadbdStatusPrefix)).c_str());
+ return true;
+}
+
static void sideload_host_service(unique_fd sfd, const std::string& args) {
int64_t file_size;
int block_size;
if ((sscanf(args.c_str(), "%" SCNd64 ":%d", &file_size, &block_size) != 2) || file_size <= 0 ||
block_size <= 0) {
- printf("bad sideload-host arguments: %s\n", args.c_str());
- exit(1);
+ LOG(ERROR) << "bad sideload-host arguments: " << args;
+ exit(kMinadbdPackageSizeError);
}
- printf("sideload-host file size %" PRId64 " block size %d\n", file_size, block_size);
+ LOG(INFO) << "sideload-host file size " << file_size << ", block size " << block_size;
+
+ if (!WriteCommandToFd(MinadbdCommands::kInstall, minadbd_socket)) {
+ exit(kMinadbdSocketIOError);
+ }
auto adb_data_reader =
std::make_unique<FuseAdbDataProvider>(std::move(sfd), file_size, block_size);
- int result = run_fuse_sideload(std::move(adb_data_reader));
+ if (int result = run_fuse_sideload(std::move(adb_data_reader)); result != 0) {
+ LOG(ERROR) << "Failed to start fuse";
+ exit(kMinadbdFuseStartError);
+ }
+
+ MinadbdCommandStatus status;
+ if (!WaitForCommandStatus(minadbd_socket, &status)) {
+ exit(kMinadbdMessageFormatError);
+ }
+ LOG(INFO) << "Got command status: " << static_cast<unsigned int>(status);
- printf("sideload_host finished\n");
- exit(result == 0 ? 0 : 1);
+ LOG(INFO) << "sideload_host finished";
+ exit(kMinadbdSuccess);
}
unique_fd daemon_service_to_fd(std::string_view name, atransport* /* transport */) {
if (name.starts_with("sideload:")) {
// This exit status causes recovery to print a special error message saying to use a newer adb
// (that supports sideload-host).
- exit(3);
+ exit(kMinadbdAdbVersionError);
} else if (name.starts_with("sideload-host:")) {
std::string arg(name.substr(strlen("sideload-host:")));
return create_service_thread("sideload-host",
diff --git a/minadbd/minadbd.h b/minadbd/minadbd_services.h
index 3570a5da5..6835bd770 100644
--- a/minadbd/minadbd.h
+++ b/minadbd/minadbd_services.h
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-#ifndef MINADBD_H__
-#define MINADBD_H__
+#pragma once
-int minadbd_main();
-
-#endif
+void SetMinadbdSocketFd(int socket_fd);
diff --git a/minadbd/minadbd_types.h b/minadbd/minadbd_types.h
new file mode 100644
index 000000000..7bd69096a
--- /dev/null
+++ b/minadbd/minadbd_types.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+// The message between recovery and minadbd is 8 bytes in size unless the length is explicitly
+// specified. Both the command and status has the format |prefix(4 bytes) + encoded enum(4 bytes)|.
+constexpr size_t kMinadbdMessageSize = 8;
+constexpr char const kMinadbdCommandPrefix[] = "COMD";
+constexpr char const kMinadbdStatusPrefix[] = "STAT";
+
+enum MinadbdErrorCode : int {
+ kMinadbdSuccess = 0,
+ kMinadbdArgumentsParsingError = 1,
+ kMinadbdSocketIOError = 2,
+ kMinadbdMessageFormatError = 3,
+ kMinadbdAdbVersionError = 4,
+ kMinadbdPackageSizeError = 5,
+ kMinadbdFuseStartError = 6,
+ kMinadbdUnsupportedCommandError = 7,
+ kMinadbdCommandExecutionError = 8,
+ kMinadbdErrorUnknown = 9,
+};
+
+enum class MinadbdCommandStatus : uint32_t {
+ kSuccess = 0,
+ kFailure = 1,
+};
+
+enum class MinadbdCommands : uint32_t {
+ kInstall = 0,
+ kUiPrint = 1,
+ kError = 2,
+};
+
+static_assert(kMinadbdMessageSize == sizeof(kMinadbdCommandPrefix) - 1 + sizeof(MinadbdCommands));
+static_assert(kMinadbdMessageSize ==
+ sizeof(kMinadbdStatusPrefix) - 1 + sizeof(MinadbdCommandStatus));