summaryrefslogtreecommitdiffstats
path: root/adb_install.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'adb_install.cpp')
-rw-r--r--adb_install.cpp170
1 files changed, 123 insertions, 47 deletions
diff --git a/adb_install.cpp b/adb_install.cpp
index ac0130651..291708c69 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -16,6 +16,7 @@
#include "adb_install.h"
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
@@ -24,115 +25,190 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdio.h>
#include <unistd.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/unique_fd.h>
+#include "ui.h"
+#include "cutils/properties.h"
#include "common.h"
#include "fuse_sideload.h"
-#include "install.h"
-#include "ui.h"
+#ifdef USE_OLD_VERIFIER
+#include "verifier24/verifier.h"
+#else
+#include "verifier.h"
+#endif
static void set_usb_driver(bool enabled) {
- // USB configfs doesn't use /s/c/a/a/enable.
- if (android::base::GetBoolProperty("sys.usb.configfs", false)) {
+ char configfs[PROPERTY_VALUE_MAX];
+ property_get("sys.usb.configfs", configfs, "false");
+ if (strcmp(configfs, "false") == 0 || strcmp(configfs, "0") == 0)
return;
- }
- static constexpr const char* USB_DRIVER_CONTROL = "/sys/class/android_usb/android0/enable";
- android::base::unique_fd fd(open(USB_DRIVER_CONTROL, O_WRONLY));
- if (fd == -1) {
- PLOG(ERROR) << "Failed to open driver control";
+ int fd = open("/sys/class/android_usb/android0/enable", O_WRONLY);
+ if (fd < 0) {
+/* These error messages show when built in older Android branches (e.g. Gingerbread)
+ It's not a critical error so we're disabling the error messages.
+ ui->Print("failed to open driver control: %s\n", strerror(errno));
+*/
+ printf("failed to open driver control: %s\n", strerror(errno));
return;
}
- // Not using android::base::WriteStringToFile since that will open with O_CREAT and give EPERM
- // when USB_DRIVER_CONTROL doesn't exist. When it gives EPERM, we don't know whether that's due
- // to non-existent USB_DRIVER_CONTROL or indeed a permission issue.
- if (!android::base::WriteStringToFd(enabled ? "1" : "0", fd)) {
- PLOG(ERROR) << "Failed to set driver control";
+
+ if (TEMP_FAILURE_RETRY(write(fd, enabled ? "1" : "0", 1)) == -1) {
+/*
+ ui->Print("failed to set driver control: %s\n", strerror(errno));
+*/
+ printf("failed to set driver control: %s\n", strerror(errno));
+ }
+ if (close(fd) < 0) {
+/*
+ ui->Print("failed to close driver control: %s\n", strerror(errno));
+*/
+ printf("failed to close driver control: %s\n", strerror(errno));
+ }
+}
+
+// On Android 8.0 for some reason init can't seem to completely stop adbd
+// so we have to kill it too if it doesn't die on its own.
+static void kill_adbd() {
+ DIR* dir = opendir("/proc");
+ if (dir) {
+ struct dirent* de = 0;
+
+ while ((de = readdir(dir)) != 0) {
+ if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+ continue;
+
+ int pid = -1;
+ int ret = sscanf(de->d_name, "%d", &pid);
+
+ if (ret == 1) {
+ char cmdpath[PATH_MAX];
+ sprintf(cmdpath, "/proc/%d/cmdline", pid);
+
+ FILE* file = fopen(cmdpath, "r");
+ size_t task_size = PATH_MAX;
+ char task[PATH_MAX];
+ char* p = task;
+ if (getline(&p, &task_size, file) > 0) {
+ if (strstr(task, "adbd") != 0) {
+ printf("adbd pid %d found, sending kill.\n", pid);
+ kill(pid, SIGINT);
+ usleep(5000);
+ kill(pid, SIGKILL);
+ }
+ }
+ fclose(file);
+ }
+ }
+ closedir(dir);
}
}
static void stop_adbd() {
- ui->Print("Stopping adbd...\n");
- android::base::SetProperty("ctl.stop", "adbd");
+ printf("Stopping adbd...\n");
+ property_set("ctl.stop", "adbd");
+ usleep(5000);
+ kill_adbd();
set_usb_driver(false);
}
+static bool is_ro_debuggable() {
+ char value[PROPERTY_VALUE_MAX+1];
+ return (property_get("ro.debuggable", value, NULL) == 1 && value[0] == '1');
+}
+
static void maybe_restart_adbd() {
if (is_ro_debuggable()) {
- ui->Print("Restarting adbd...\n");
+ printf("Restarting adbd...\n");
set_usb_driver(true);
- android::base::SetProperty("ctl.start", "adbd");
+ property_set("ctl.start", "adbd");
}
}
-int apply_from_adb(bool* wipe_cache, const char* install_file) {
- modified_flash = true;
+// How long (in seconds) we wait for the host to start sending us a
+// package, before timing out.
+#define ADB_INSTALL_TIMEOUT 300
+
+int
+apply_from_adb(const char* install_file, pid_t* child_pid) {
stop_adbd();
set_usb_driver(true);
+/*
+int apply_from_adb(RecoveryUI* ui, bool* wipe_cache, const char* install_file) {
+ modified_flash = true;
- ui->Print(
- "\n\nNow send the package you want to apply\n"
- "to the device with \"adb sideload <filename>\"...\n");
+ stop_adbd(ui);
+ set_usb_driver(ui, true);
+ ui->Print("\n\nNow send the package you want to apply\n"
+ "to the device with \"adb sideload <filename>\"...\n");
+*/
pid_t child;
if ((child = fork()) == 0) {
- execl("/sbin/recovery", "recovery", "--adbd", nullptr);
- _exit(EXIT_FAILURE);
+ execl("/sbin/recovery", "recovery", "--adbd", install_file, NULL);
+ _exit(-1);
}
- // How long (in seconds) we wait for the host to start sending us a package, before timing out.
- static constexpr int ADB_INSTALL_TIMEOUT = 300;
+ *child_pid = child;
+ // caller can now kill the child thread from another thread
- // FUSE_SIDELOAD_HOST_PATHNAME will start to exist once the host connects and starts serving a
- // package. Poll for its appearance. (Note that inotify doesn't work with FUSE.)
+ // FUSE_SIDELOAD_HOST_PATHNAME will start to exist once the host
+ // connects and starts serving a package. Poll for its
+ // appearance. (Note that inotify doesn't work with FUSE.)
int result = INSTALL_ERROR;
int status;
bool waited = false;
+ struct stat st;
for (int i = 0; i < ADB_INSTALL_TIMEOUT; ++i) {
if (waitpid(child, &status, WNOHANG) != 0) {
- result = INSTALL_ERROR;
+ result = -1;
waited = true;
break;
}
- struct stat st;
if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
- if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT - 1) {
+ if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT-1) {
sleep(1);
continue;
} else {
- ui->Print("\nTimed out waiting for package.\n\n");
- result = INSTALL_ERROR;
+ printf("\nTimed out waiting for package: %s\n\n", strerror(errno));
+ result = -1;
kill(child, SIGKILL);
break;
}
}
- result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false, 0);
- break;
+ // Install is handled elsewhere in TWRP
+ //install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false);
+ return 0;
}
+ // if we got here, something failed
+ *child_pid = 0;
+
if (!waited) {
- // Calling stat() on this magic filename signals the minadbd subprocess to shut down.
- struct stat st;
+ // Calling stat() on this magic filename signals the minadbd
+ // subprocess to shut down.
stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st);
- // TODO: there should be a way to cancel waiting for a package (by pushing some button combo on
- // the device). For now you just have to 'adb sideload' a file that's not a valid package, like
- // "/dev/null".
+ // TODO(dougz): there should be a way to cancel waiting for a
+ // package (by pushing some button combo on the device). For now
+ // you just have to 'adb sideload' a file that's not a valid
+ // package, like "/dev/null".
waitpid(child, &status, 0);
}
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
if (WEXITSTATUS(status) == 3) {
- ui->Print("\nYou need adb 1.0.32 or newer to sideload\nto this device.\n\n");
+ printf("\nYou need adb 1.0.32 or newer to sideload\nto this device.\n\n");
+ result = -2;
} else if (!WIFSIGNALED(status)) {
- ui->Print("\n(adbd status %d)\n", WEXITSTATUS(status));
+ printf("adbd status %d\n", WEXITSTATUS(status));
}
}