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
This commit is contained in:
Hridya Valsaraju 2018-08-31 11:57:51 -07:00
parent a062fae9d7
commit e4ef453914
5 changed files with 47 additions and 50 deletions

View file

@ -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 @@ 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;
}

View file

@ -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

View file

@ -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"

View file

@ -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());

View file

@ -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.