adb: Modernize the service creation

This change removes the void* argument passing and instead uses C++11
features to avoid having to handle memory manually.

Bug: None
Test: python ./system/core/adb/test_device.py

Change-Id: I6380245b2ca583591810e3e363c67c993a107621
This commit is contained in:
Luis Hector Chavez 2018-07-18 19:40:12 -07:00
parent c20c85008d
commit 095792c300
10 changed files with 204 additions and 181 deletions

View File

@ -156,11 +156,6 @@ int create_jdwp_connection_fd(int jdwp_pid);
int handle_forward_request(const char* service, atransport* transport, int reply_fd);
#if !ADB_HOST
void framebuffer_service(int fd, void* cookie);
void set_verity_enabled_state_service(int fd, void* cookie);
#endif
/* packet allocator */
apacket* get_apacket(void);
void put_apacket(apacket* p);

View File

@ -525,12 +525,11 @@ static bool handle_sync_command(int fd, std::vector<char>& buffer) {
return true;
}
void file_sync_service(int fd, void*) {
void file_sync_service(android::base::unique_fd fd) {
std::vector<char> buffer(SYNC_DATA_MAX);
while (handle_sync_command(fd, buffer)) {
while (handle_sync_command(fd.get(), buffer)) {
}
D("sync: done");
adb_close(fd);
}

View File

@ -14,6 +14,8 @@
* limitations under the License.
*/
#include "framebuffer_service.h"
#include <errno.h>
#include <fcntl.h>
#include <linux/fb.h>
@ -55,8 +57,7 @@ struct fbinfo {
unsigned int alpha_length;
} __attribute__((packed));
void framebuffer_service(int fd, void *cookie)
{
void framebuffer_service(android::base::unique_fd fd) {
struct fbinfo fbinfo;
unsigned int i, bsize;
char buf[640];
@ -65,7 +66,7 @@ void framebuffer_service(int fd, void *cookie)
int fds[2];
pid_t pid;
if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
if (pipe2(fds, O_CLOEXEC) < 0) return;
pid = fork();
if (pid < 0) goto done;
@ -168,7 +169,7 @@ void framebuffer_service(int fd, void *cookie)
}
/* write header */
if(!WriteFdExactly(fd, &fbinfo, sizeof(fbinfo))) goto done;
if (!WriteFdExactly(fd.get(), &fbinfo, sizeof(fbinfo))) goto done;
/* write data */
for(i = 0; i < fbinfo.size; i += bsize) {
@ -176,13 +177,11 @@ void framebuffer_service(int fd, void *cookie)
if (i + bsize > fbinfo.size)
bsize = fbinfo.size - i;
if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
if(!WriteFdExactly(fd, buf, bsize)) goto done;
if (!WriteFdExactly(fd.get(), buf, bsize)) goto done;
}
done:
adb_close(fds[0]);
TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0));
pipefail:
adb_close(fd);
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (C) 2018 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 _DAEMON_FRAMEBUFFER_SERVICE_H_
#define _DAEMON_FRAMEBUFFER_SERVICE_H_
#include <android-base/unique_fd.h>
void framebuffer_service(android::base::unique_fd fd);
#endif // _DAEMON_FRAMEBUFFER_SERVICE_H_

View File

@ -44,6 +44,7 @@
#include "adb_unique_fd.h"
#include "adb_utils.h"
#include "fs_mgr.h"
#include "set_verity_enable_state_service.h"
// Returns the device used to mount a directory in /proc/mounts.
static std::string find_proc_mount(const char* dir) {
@ -218,14 +219,11 @@ static void reboot_for_remount(int fd, bool need_fsck) {
android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_cmd.c_str());
}
void remount_service(int fd, void* cookie) {
unique_fd close_fd(fd);
const char* cmd = reinterpret_cast<const char*>(cookie);
bool user_requested_reboot = cmd && !strcmp(cmd, "-R");
void remount_service(android::base::unique_fd fd, const std::string& cmd) {
bool user_requested_reboot = cmd != "-R";
if (getuid() != 0) {
WriteFdExactly(fd, "Not running as root. Try \"adb root\" first.\n");
WriteFdExactly(fd.get(), "Not running as root. Try \"adb root\" first.\n");
return;
}
@ -246,7 +244,7 @@ void remount_service(int fd, void* cookie) {
if (dev.empty() || !fs_has_shared_blocks(dev.c_str())) {
continue;
}
if (can_unshare_blocks(fd, dev.c_str())) {
if (can_unshare_blocks(fd.get(), dev.c_str())) {
dedup.emplace(partition);
}
}
@ -257,12 +255,12 @@ void remount_service(int fd, void* cookie) {
if (user_requested_reboot) {
if (!dedup.empty() || verity_enabled) {
if (verity_enabled) {
set_verity_enabled_state_service(fd, nullptr);
set_verity_enabled_state_service(android::base::unique_fd(dup(fd.get())), false);
}
reboot_for_remount(fd, !dedup.empty());
reboot_for_remount(fd.get(), !dedup.empty());
return;
}
WriteFdExactly(fd, "No reboot needed, skipping -R.\n");
WriteFdExactly(fd.get(), "No reboot needed, skipping -R.\n");
}
// If we need to disable-verity, but we also need to perform a recovery
@ -271,17 +269,14 @@ void remount_service(int fd, void* cookie) {
if (verity_enabled && dedup.empty()) {
// Allow remount but warn of likely bad effects
bool both = system_verified && vendor_verified;
WriteFdFmt(fd,
"dm_verity is enabled on the %s%s%s partition%s.\n",
system_verified ? "system" : "",
both ? " and " : "",
vendor_verified ? "vendor" : "",
both ? "s" : "");
WriteFdExactly(fd,
WriteFdFmt(fd.get(), "dm_verity is enabled on the %s%s%s partition%s.\n",
system_verified ? "system" : "", both ? " and " : "",
vendor_verified ? "vendor" : "", both ? "s" : "");
WriteFdExactly(fd.get(),
"Use \"adb disable-verity\" to disable verity.\n"
"If you do not, remount may succeed, however, you will still "
"not be able to write to these volumes.\n");
WriteFdExactly(fd,
WriteFdExactly(fd.get(),
"Alternately, use \"adb remount -R\" to disable verity "
"and automatically reboot.\n");
}
@ -292,29 +287,29 @@ void remount_service(int fd, void* cookie) {
if (dedup.count(partition)) {
continue;
}
success &= remount_partition(fd, partition.c_str());
success &= remount_partition(fd.get(), partition.c_str());
}
if (!dedup.empty()) {
WriteFdExactly(fd,
WriteFdExactly(fd.get(),
"The following partitions are deduplicated and cannot "
"yet be remounted:\n");
for (const std::string& name : dedup) {
WriteFdFmt(fd, " %s\n", name.c_str());
WriteFdFmt(fd.get(), " %s\n", name.c_str());
}
WriteFdExactly(fd,
WriteFdExactly(fd.get(),
"To reboot and un-deduplicate the listed partitions, "
"please retry with adb remount -R.\n");
if (system_verified || vendor_verified) {
WriteFdExactly(fd, "Note: verity will be automatically disabled after reboot.\n");
WriteFdExactly(fd.get(), "Note: verity will be automatically disabled after reboot.\n");
}
return;
}
if (!success) {
WriteFdExactly(fd, "remount failed\n");
WriteFdExactly(fd.get(), "remount failed\n");
} else {
WriteFdExactly(fd, "remount succeeded\n");
WriteFdExactly(fd.get(), "remount succeeded\n");
}
}

View File

@ -16,6 +16,7 @@
#define TRACE_TAG ADB
#include "set_verity_enable_state_service.h"
#include "sysdeps.h"
#include <fcntl.h>
@ -25,8 +26,8 @@
#include <stdio.h>
#include <sys/stat.h>
#include "android-base/properties.h"
#include "android-base/stringprintf.h"
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <log/log_properties.h>
#include "adb.h"
@ -131,12 +132,9 @@ static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity
return true;
}
void set_verity_enabled_state_service(int fd, void* cookie) {
unique_fd closer(fd);
void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable) {
bool any_changed = false;
bool enable = (cookie != nullptr);
// Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
// contract, androidboot.vbmeta.digest is set by the bootloader
// when using AVB).
@ -147,12 +145,12 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// VB1.0 dm-verity is only enabled on certain builds.
if (!using_avb) {
if (!kAllowDisableVerity) {
WriteFdFmt(fd, "%s-verity only works for userdebug builds\n",
WriteFdFmt(fd.get(), "%s-verity only works for userdebug builds\n",
enable ? "enable" : "disable");
}
if (!android::base::GetBoolProperty("ro.secure", false)) {
WriteFdFmt(fd, "verity not enabled - ENG build\n");
WriteFdFmt(fd.get(), "verity not enabled - ENG build\n");
return;
}
}
@ -160,7 +158,7 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// Should never be possible to disable dm-verity on a USER build
// regardless of using AVB or VB1.0.
if (!__android_log_is_debuggable()) {
WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n");
WriteFdFmt(fd.get(), "verity cannot be disabled/enabled - USER build\n");
return;
}
@ -168,10 +166,10 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// Yep, the system is using AVB.
AvbOps* ops = avb_ops_user_new();
if (ops == nullptr) {
WriteFdFmt(fd, "Error getting AVB ops\n");
WriteFdFmt(fd.get(), "Error getting AVB ops\n");
return;
}
if (set_avb_verity_enabled_state(fd, ops, enable)) {
if (set_avb_verity_enabled_state(fd.get(), ops, enable)) {
any_changed = true;
}
avb_ops_user_free(ops);
@ -181,14 +179,14 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
// read all fstab entries at once from all sources
fstab = fs_mgr_read_fstab_default();
if (!fstab) {
WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
WriteFdFmt(fd.get(), "Failed to read fstab\nMaybe run adb root?\n");
return;
}
// Loop through entries looking for ones that vold manages.
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,
if (set_verity_enabled_state(fd.get(), fstab->recs[i].blk_device,
fstab->recs[i].mount_point, enable)) {
any_changed = true;
}
@ -197,6 +195,6 @@ void set_verity_enabled_state_service(int fd, void* cookie) {
}
if (any_changed) {
WriteFdFmt(fd, "Now reboot your device for settings to take effect\n");
WriteFdFmt(fd.get(), "Now reboot your device for settings to take effect\n");
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (C) 2018 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 _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
#define _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
#include <android-base/unique_fd.h>
void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable);
#endif // _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_

View File

@ -20,6 +20,8 @@
#include <string>
#include <vector>
#include <android-base/unique_fd.h>
#define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
#define ID_LSTAT_V1 MKID('S','T','A','T')
@ -79,7 +81,7 @@ union syncmsg {
} status;
};
void file_sync_service(int fd, void* cookie);
void file_sync_service(android::base::unique_fd fd);
bool do_sync_ls(const char* path);
bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync);
bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst,

View File

@ -19,7 +19,9 @@
#include <string>
#include <android-base/unique_fd.h>
bool make_block_device_writable(const std::string&);
void remount_service(int, void*);
void remount_service(android::base::unique_fd, const std::string&);
#endif

View File

@ -37,6 +37,7 @@
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/sockets.h>
#if !ADB_HOST
@ -49,6 +50,10 @@
#include "adb.h"
#include "adb_io.h"
#include "adb_utils.h"
#if !ADB_HOST
#include "daemon/framebuffer_service.h"
#include "daemon/set_verity_enable_state_service.h"
#endif
#include "file_sync_service.h"
#include "remount_service.h"
#include "services.h"
@ -57,81 +62,67 @@
#include "sysdeps.h"
#include "transport.h"
struct stinfo {
const char* service_name;
void (*func)(int fd, void *cookie);
int fd;
void *cookie;
};
namespace {
static void service_bootstrap_func(void* x) {
stinfo* sti = reinterpret_cast<stinfo*>(x);
adb_thread_setname(android::base::StringPrintf("%s svc %d", sti->service_name, sti->fd));
sti->func(sti->fd, sti->cookie);
free(sti);
void service_bootstrap_func(std::string service_name,
std::function<void(android::base::unique_fd)> func,
android::base::unique_fd fd) {
adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get()));
func(std::move(fd));
}
#if !ADB_HOST
void restart_root_service(int fd, void *cookie) {
void restart_root_service(android::base::unique_fd fd) {
if (getuid() == 0) {
WriteFdExactly(fd, "adbd is already running as root\n");
adb_close(fd);
} else {
if (!__android_log_is_debuggable()) {
WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
adb_close(fd);
return;
}
android::base::SetProperty("service.adb.root", "1");
WriteFdExactly(fd, "restarting adbd as root\n");
adb_close(fd);
WriteFdExactly(fd.get(), "adbd is already running as root\n");
return;
}
if (!__android_log_is_debuggable()) {
WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
return;
}
android::base::SetProperty("service.adb.root", "1");
WriteFdExactly(fd.get(), "restarting adbd as root\n");
}
void restart_unroot_service(int fd, void *cookie) {
void restart_unroot_service(android::base::unique_fd fd) {
if (getuid() != 0) {
WriteFdExactly(fd, "adbd not running as root\n");
adb_close(fd);
} else {
android::base::SetProperty("service.adb.root", "0");
WriteFdExactly(fd, "restarting adbd as non root\n");
adb_close(fd);
WriteFdExactly(fd.get(), "adbd not running as root\n");
return;
}
android::base::SetProperty("service.adb.root", "0");
WriteFdExactly(fd.get(), "restarting adbd as non root\n");
}
void restart_tcp_service(int fd, void *cookie) {
int port = (int) (uintptr_t) cookie;
void restart_tcp_service(android::base::unique_fd fd, int port) {
if (port <= 0) {
WriteFdFmt(fd, "invalid port %d\n", port);
adb_close(fd);
WriteFdFmt(fd.get(), "invalid port %d\n", port);
return;
}
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);
WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
}
void restart_usb_service(int fd, void *cookie) {
void restart_usb_service(android::base::unique_fd fd) {
android::base::SetProperty("service.adb.tcp.port", "0");
WriteFdExactly(fd, "restarting in USB mode\n");
adb_close(fd);
WriteFdExactly(fd.get(), "restarting in USB mode\n");
}
static bool reboot_service_impl(int fd, const char* arg) {
const char* reboot_arg = arg;
bool reboot_service_impl(android::base::unique_fd fd, const std::string& arg) {
std::string reboot_arg = arg;
bool auto_reboot = false;
if (strcmp(reboot_arg, "sideload-auto-reboot") == 0) {
if (reboot_arg == "sideload-auto-reboot") {
auto_reboot = true;
reboot_arg = "sideload";
}
// It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
// in the command file.
if (strcmp(reboot_arg, "sideload") == 0) {
if (reboot_arg == "sideload") {
if (getuid() != 0) {
WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
return false;
@ -151,8 +142,8 @@ static bool reboot_service_impl(int fd, const char* arg) {
sync();
if (!reboot_arg || !reboot_arg[0]) reboot_arg = "adb";
std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg);
if (reboot_arg.empty()) reboot_arg = "adb";
std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str());
return false;
@ -161,23 +152,19 @@ static bool reboot_service_impl(int fd, const char* arg) {
return true;
}
void reboot_service(int fd, void* arg) {
if (reboot_service_impl(fd, static_cast<const char*>(arg))) {
// Don't return early. Give the reboot command time to take effect
// to avoid messing up scripts which do "adb reboot && adb wait-for-device"
while (true) {
pause();
}
void reboot_service(android::base::unique_fd fd, const std::string& arg) {
if (!reboot_service_impl(std::move(fd), arg)) {
return;
}
// Don't return early. Give the reboot command time to take effect
// to avoid messing up scripts which do "adb reboot && adb wait-for-device"
while (true) {
pause();
}
free(arg);
adb_close(fd);
}
static void reconnect_service(int fd, void* arg) {
void reconnect_service(android::base::unique_fd fd, atransport* t) {
WriteFdExactly(fd, "done");
adb_close(fd);
atransport* t = static_cast<atransport*>(arg);
kick_transport(t);
}
@ -197,7 +184,7 @@ int reverse_service(const char* command, atransport* transport) {
// Shell service string can look like:
// shell[,arg1,arg2,...]:[command]
static int ShellService(const std::string& args, const atransport* transport) {
int ShellService(const std::string& args, const atransport* transport) {
size_t delimiter_index = args.find(':');
if (delimiter_index == std::string::npos) {
LOG(ERROR) << "No ':' found in shell service arguments: " << args;
@ -236,16 +223,17 @@ static int ShellService(const std::string& args, const atransport* transport) {
#endif // !ADB_HOST
static int create_service_thread(const char* service_name, void (*func)(int, void*), void* cookie) {
android::base::unique_fd create_service_thread(const char* service_name,
std::function<void(android::base::unique_fd)> func) {
int s[2];
if (adb_socketpair(s)) {
printf("cannot create service socket pair\n");
return -1;
return android::base::unique_fd();
}
D("socketpair: (%d,%d)", s[0], s[1]);
#if !ADB_HOST
if (func == &file_sync_service) {
if (strcmp(service_name, "sync") == 0) {
// Set file sync service socket to maximum size
int max_buf = LINUX_MAX_SOCKET_SIZE;
adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
@ -253,21 +241,14 @@ static int create_service_thread(const char* service_name, void (*func)(int, voi
}
#endif // !ADB_HOST
stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
if (sti == nullptr) {
fatal("cannot allocate stinfo");
}
sti->service_name = service_name;
sti->func = func;
sti->cookie = cookie;
sti->fd = s[1];
std::thread(service_bootstrap_func, sti).detach();
std::thread(service_bootstrap_func, service_name, func, android::base::unique_fd(s[1])).detach();
D("service thread started, %d:%d",s[0], s[1]);
return s[0];
return android::base::unique_fd(s[0]);
}
} // namespace
int service_to_fd(const char* name, atransport* transport) {
int ret = -1;
@ -280,54 +261,60 @@ int service_to_fd(const char* name, atransport* transport) {
#if !ADB_HOST
} else if(!strncmp("dev:", name, 4)) {
ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
} else if(!strncmp(name, "framebuffer:", 12)) {
ret = create_service_thread("fb", framebuffer_service, nullptr);
} else if (!strncmp(name, "framebuffer:", 12)) {
ret = create_service_thread("fb", framebuffer_service).release();
} else if (!strncmp(name, "jdwp:", 5)) {
ret = create_jdwp_connection_fd(atoi(name+5));
} else if(!strncmp(name, "shell", 5)) {
ret = create_jdwp_connection_fd(atoi(name + 5));
} else if (!strncmp(name, "shell", 5)) {
ret = ShellService(name + 5, transport);
} else if(!strncmp(name, "exec:", 5)) {
} else if (!strncmp(name, "exec:", 5)) {
ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if(!strncmp(name, "sync:", 5)) {
ret = create_service_thread("sync", file_sync_service, nullptr);
} else if(!strncmp(name, "remount:", 8)) {
const char* options = name + strlen("remount:");
void* cookie = const_cast<void*>(reinterpret_cast<const void*>(options));
ret = create_service_thread("remount", remount_service, cookie);
} else if(!strncmp(name, "reboot:", 7)) {
void* arg = strdup(name + 7);
if (arg == NULL) return -1;
ret = create_service_thread("reboot", reboot_service, arg);
if (ret < 0) free(arg);
} else if(!strncmp(name, "root:", 5)) {
ret = create_service_thread("root", restart_root_service, nullptr);
} else if(!strncmp(name, "unroot:", 7)) {
ret = create_service_thread("unroot", restart_unroot_service, nullptr);
} else if(!strncmp(name, "backup:", 7)) {
ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
(name + 7)).c_str(),
nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if(!strncmp(name, "restore:", 8)) {
} else if (!strncmp(name, "sync:", 5)) {
ret = create_service_thread("sync", file_sync_service).release();
} else if (!strncmp(name, "remount:", 8)) {
std::string options(name + strlen("remount:"));
ret = create_service_thread("remount",
std::bind(remount_service, std::placeholders::_1, options))
.release();
} else if (!strncmp(name, "reboot:", 7)) {
std::string arg(name + strlen("reboot:"));
ret = create_service_thread("reboot", std::bind(reboot_service, std::placeholders::_1, arg))
.release();
} else if (!strncmp(name, "root:", 5)) {
ret = create_service_thread("root", restart_root_service).release();
} else if (!strncmp(name, "unroot:", 7)) {
ret = create_service_thread("unroot", restart_unroot_service).release();
} else if (!strncmp(name, "backup:", 7)) {
ret = StartSubprocess(
android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(),
nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
} else if (!strncmp(name, "restore:", 8)) {
ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
SubprocessProtocol::kNone);
} else if(!strncmp(name, "tcpip:", 6)) {
} else if (!strncmp(name, "tcpip:", 6)) {
int port;
if (sscanf(name + 6, "%d", &port) != 1) {
return -1;
}
ret = create_service_thread("tcp", restart_tcp_service, reinterpret_cast<void*>(port));
} else if(!strncmp(name, "usb:", 4)) {
ret = create_service_thread("usb", restart_usb_service, nullptr);
ret = create_service_thread("tcp",
std::bind(restart_tcp_service, std::placeholders::_1, port))
.release();
} else if (!strncmp(name, "usb:", 4)) {
ret = create_service_thread("usb", restart_usb_service).release();
} else if (!strncmp(name, "reverse:", 8)) {
ret = reverse_service(name + 8, transport);
} else if(!strncmp(name, "disable-verity:", 15)) {
ret = create_service_thread("verity-on", set_verity_enabled_state_service,
reinterpret_cast<void*>(0));
} else if(!strncmp(name, "enable-verity:", 15)) {
ret = create_service_thread("verity-off", set_verity_enabled_state_service,
reinterpret_cast<void*>(1));
} else if (!strncmp(name, "disable-verity:", 15)) {
ret = create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
std::placeholders::_1, false))
.release();
} else if (!strncmp(name, "enable-verity:", 15)) {
ret = create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
std::placeholders::_1, true))
.release();
} else if (!strcmp(name, "reconnect")) {
ret = create_service_thread("reconnect", reconnect_service, transport);
ret = create_service_thread("reconnect",
std::bind(reconnect_service, std::placeholders::_1, transport))
.release();
#endif
}
if (ret >= 0) {
@ -420,19 +407,16 @@ void connect_emulator(const std::string& port_spec, std::string* response) {
}
}
static void connect_service(int fd, void* data) {
char* host = reinterpret_cast<char*>(data);
static void connect_service(android::base::unique_fd fd, std::string host) {
std::string response;
if (!strncmp(host, "emu:", 4)) {
connect_emulator(host + 4, &response);
if (!strncmp(host.c_str(), "emu:", 4)) {
connect_emulator(host.c_str() + 4, &response);
} else {
connect_device(host, &response);
connect_device(host.c_str(), &response);
}
free(host);
// Send response for emulator and device
SendProtocolString(fd, response);
adb_close(fd);
SendProtocolString(fd.get(), response);
}
#endif
@ -445,7 +429,7 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI
} else if (android::base::StartsWith(name, "wait-for-")) {
name += strlen("wait-for-");
std::unique_ptr<state_info> sinfo(new state_info);
std::unique_ptr<state_info> sinfo = std::make_unique<state_info>();
if (sinfo == nullptr) {
fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
return nullptr;
@ -481,17 +465,18 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI
return nullptr;
}
int fd = create_service_thread("wait", wait_for_state, sinfo.get());
int fd = create_service_thread(
"wait", std::bind(wait_for_state, std::placeholders::_1, sinfo.get()))
.release();
if (fd != -1) {
sinfo.release();
}
return create_local_socket(fd);
} else if (!strncmp(name, "connect:", 8)) {
char* host = strdup(name + 8);
int fd = create_service_thread("connect", connect_service, host);
if (fd == -1) {
free(host);
}
std::string host(name + strlen("connect:"));
int fd = create_service_thread("connect",
std::bind(connect_service, std::placeholders::_1, host))
.release();
return create_local_socket(fd);
}
return nullptr;