diff --git a/adb_install.cpp b/adb_install.cpp index 97dff221..438da9fc 100644 --- a/adb_install.cpp +++ b/adb_install.cpp @@ -26,55 +26,23 @@ #include #include -#include #include #include -#include #include "common.h" #include "fuse_sideload.h" #include "install.h" #include "ui.h" -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() { - ui->Print("Stopping adbd...\n"); - android::base::SetProperty("ctl.stop", "adbd"); - set_usb_driver(false); -} - -static void maybe_restart_adbd() { - if (is_ro_debuggable()) { - ui->Print("Restarting adbd...\n"); - set_usb_driver(true); - android::base::SetProperty("ctl.start", "adbd"); - } -} - int apply_from_adb(bool* wipe_cache) { modified_flash = true; - - stop_adbd(); - set_usb_driver(true); + // Save the usb state to restore after the sideload operation. + std::string usb_state = android::base::GetProperty("sys.usb.state", "none"); + // Clean up state and stop adbd. + if (usb_state != "none" && !SetUsbConfig("none")) { + LOG(ERROR) << "Failed to clear USB config"; + return INSTALL_ERROR; + } ui->Print( "\n\nNow send the package you want to apply\n" @@ -86,6 +54,11 @@ int apply_from_adb(bool* wipe_cache) { _exit(EXIT_FAILURE); } + if (!SetUsbConfig("sideload")) { + LOG(ERROR) << "Failed to set usb config to sideload"; + return INSTALL_ERROR; + } + // 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; @@ -136,8 +109,17 @@ int apply_from_adb(bool* wipe_cache) { } } - set_usb_driver(false); - maybe_restart_adbd(); + // Clean up before switching to the older state, for example setting the state + // to none sets sys/class/android_usb/android0/enable to 0. + if (!SetUsbConfig("none")) { + LOG(ERROR) << "Failed to clear USB config"; + } + + if (usb_state != "none") { + if (!SetUsbConfig(usb_state)) { + LOG(ERROR) << "Failed to set USB config to " << usb_state; + } + } return result; } diff --git a/common.h b/common.h index c24431bd..38bdd526 100644 --- a/common.h +++ b/common.h @@ -44,4 +44,5 @@ void ui_print(const char* format, ...) __printflike(1, 2); bool is_ro_debuggable(); +bool SetUsbConfig(const std::string& state); #endif // RECOVERY_COMMON_H diff --git a/etc/init.rc b/etc/init.rc index 2adecb76..fa8fe269 100644 --- a/etc/init.rc +++ b/etc/init.rc @@ -132,11 +132,9 @@ on property:sys.usb.config=adb on property:sys.usb.config=fastboot start fastbootd -on property:sys.usb.config=none - stop adbd - stop fastbootd - on property:sys.usb.config=none && property:sys.usb.configfs=0 + stop adbd + stop fastboot write /sys/class/android_usb/android0/enable 0 setprop sys.usb.state ${sys.usb.config} @@ -146,6 +144,12 @@ on property:sys.usb.config=adb && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state ${sys.usb.config} +on property:sys.usb.config=sideload && property:sys.usb.configfs=0 + write /sys/class/android_usb/android0/idProduct D001 + write /sys/class/android_usb/android0/functions adb + write /sys/class/android_usb/android0/enable 1 + setprop sys.usb.state ${sys.usb.config} + on property:sys.usb.config=fastboot && property:sys.usb.configfs=0 write /sys/class/android_usb/android0/idProduct 4EE0 write /sys/class/android_usb/android0/functions fastboot @@ -155,10 +159,19 @@ on property:sys.usb.config=fastboot && property:sys.usb.configfs=0 # Configfs triggers on property:sys.usb.config=none && property:sys.usb.configfs=1 write /config/usb_gadget/g1/UDC "none" + stop adbd + stop fastbootd setprop sys.usb.ffs.ready 0 rm /config/usb_gadget/g1/configs/b.1/f1 setprop sys.usb.state ${sys.usb.config} +on property:sys.usb.config=sideload && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1 + write /config/usb_gadget/g1/idProduct 0xD001 + write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb" + symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f1 + write /config/usb_gadget/g1/UDC ${sys.usb.controller} + setprop sys.usb.state ${sys.usb.config} + on property:sys.usb.config=adb && property:sys.usb.ffs.ready=1 && property:sys.usb.configfs=1 write /config/usb_gadget/g1/idProduct 0xD001 write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "adb" diff --git a/recovery.cpp b/recovery.cpp index 01bd83b5..5934b61d 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -286,6 +286,12 @@ static bool erase_volume(const char* volume) { return (result == 0); } +// Sets the usb config to 'state' +bool SetUsbConfig(const std::string& state) { + android::base::SetProperty("sys.usb.config", state); + return android::base::WaitForProperty("sys.usb.state", state); +} + // Returns the selected filename, or an empty string. static std::string browse_directory(const std::string& path, Device* device) { ensure_path_mounted(path.c_str()); diff --git a/recovery_main.cpp b/recovery_main.cpp index 020a5314..c3168fc2 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -305,11 +305,6 @@ static void redirect_stdio(const char* filename) { } } -static bool SetUsbConfig(const std::string& state) { - android::base::SetProperty("sys.usb.config", state); - return android::base::WaitForProperty("sys.usb.state", state); -} - int main(int argc, char** argv) { // We don't have logcat yet under recovery; so we'll print error on screen and log to stdout // (which is redirected to recovery.log) as we used to do.