Fix sideload for user devices by adding a new sideload config
Bug: 113563995
Test: Tested the 'adb sideload' command on marlin user/userdebug builds
and walleye user/userdebug builds
Change-Id: I00d565547b85f2db87012e4a08316609e03395ac
diff --git a/adb_install.cpp b/adb_install.cpp
index 97dff22..438da9f 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -26,55 +26,23 @@
#include <sys/wait.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 "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 @@
_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 @@
}
}
- 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 c24431b..38bdd52 100644
--- a/common.h
+++ b/common.h
@@ -44,4 +44,5 @@
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 2adecb7..fa8fe26 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -132,11 +132,9 @@
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 @@
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 @@
# 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 01bd83b..5934b61 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -286,6 +286,12 @@
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 020a531..c3168fc 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -305,11 +305,6 @@
}
}
-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.