summaryrefslogtreecommitdiffstats
path: root/adb_install.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'adb_install.cpp')
-rw-r--r--adb_install.cpp198
1 files changed, 102 insertions, 96 deletions
diff --git a/adb_install.cpp b/adb_install.cpp
index 79b8df91b..ac0130651 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -14,124 +14,130 @@
* limitations under the License.
*/
-#include <unistd.h>
-#include <dirent.h>
+#include "adb_install.h"
+
#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <fcntl.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 "install.h"
#include "common.h"
-#include "adb_install.h"
-#include "minadbd/fuse_adb_provider.h"
#include "fuse_sideload.h"
+#include "install.h"
+#include "ui.h"
-#include <android-base/properties.h>
-
-static void set_usb_driver(RecoveryUI* ui, bool enabled) {
- int fd = open("/sys/class/android_usb/android0/enable", O_WRONLY);
- if (fd < 0) {
- ui->Print("failed to open driver control: %s\n", strerror(errno));
- return;
- }
- if (TEMP_FAILURE_RETRY(write(fd, enabled ? "1" : "0", 1)) == -1) {
- ui->Print("failed to set driver control: %s\n", strerror(errno));
- }
- if (close(fd) < 0) {
- ui->Print("failed to close driver control: %s\n", strerror(errno));
- }
+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)) {
+ 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";
+ 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";
+ }
}
-static void stop_adbd(RecoveryUI* ui) {
- ui->Print("Stopping adbd...\n");
- android::base::SetProperty("ctl.stop", "adbd");
- set_usb_driver(ui, false);
+static void stop_adbd() {
+ ui->Print("Stopping adbd...\n");
+ android::base::SetProperty("ctl.stop", "adbd");
+ set_usb_driver(false);
}
-static void maybe_restart_adbd(RecoveryUI* ui) {
- if (is_ro_debuggable()) {
- ui->Print("Restarting adbd...\n");
- set_usb_driver(ui, true);
- android::base::SetProperty("ctl.start", "adbd");
- }
+static void maybe_restart_adbd() {
+ if (is_ro_debuggable()) {
+ ui->Print("Restarting adbd...\n");
+ set_usb_driver(true);
+ android::base::SetProperty("ctl.start", "adbd");
+ }
}
-// 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(RecoveryUI* ui, bool* wipe_cache, const char* install_file) {
- modified_flash = true;
-
- 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", NULL);
- _exit(EXIT_FAILURE);
+int apply_from_adb(bool* wipe_cache, const char* install_file) {
+ modified_flash = true;
+
+ stop_adbd();
+ set_usb_driver(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);
+ }
+
+ // 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;
+
+ // 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;
+ for (int i = 0; i < ADB_INSTALL_TIMEOUT; ++i) {
+ if (waitpid(child, &status, WNOHANG) != 0) {
+ result = INSTALL_ERROR;
+ waited = true;
+ break;
}
- // 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;
- waited = true;
- break;
- }
-
- if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
- if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT-1) {
- sleep(1);
- continue;
- } else {
- ui->Print("\nTimed out waiting for package.\n\n");
- result = INSTALL_ERROR;
- kill(child, SIGKILL);
- break;
- }
- }
- result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false, 0);
+ if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
+ if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT - 1) {
+ sleep(1);
+ continue;
+ } else {
+ ui->Print("\nTimed out waiting for package.\n\n");
+ result = INSTALL_ERROR;
+ kill(child, SIGKILL);
break;
+ }
}
+ result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false, 0);
+ break;
+ }
- if (!waited) {
- // Calling stat() on this magic filename signals the minadbd
- // subprocess to shut down.
- stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st);
-
- // 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");
- } else if (!WIFSIGNALED(status)) {
- ui->Print("\n(adbd status %d)\n", WEXITSTATUS(status));
- }
+ if (!waited) {
+ // Calling stat() on this magic filename signals the minadbd subprocess to shut down.
+ struct stat st;
+ 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".
+ 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");
+ } else if (!WIFSIGNALED(status)) {
+ ui->Print("\n(adbd status %d)\n", WEXITSTATUS(status));
}
+ }
- set_usb_driver(ui, false);
- maybe_restart_adbd(ui);
+ set_usb_driver(false);
+ maybe_restart_adbd();
- return result;
+ return result;
}