1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <unistd.h> 18 #include <dirent.h> 19 #include <errno.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/types.h> 23 #include <sys/wait.h> 24 #include <sys/stat.h> 25 #include <signal.h> 26 #include <fcntl.h> 27 28 #include "ui.h" 29 #include "cutils/properties.h" 30 #include "install.h" 31 #include "common.h" 32 #include "adb_install.h" 33 extern "C" { 34 #include "minadbd/adb.h" 35 } 36 37 static RecoveryUI* ui = NULL; 38 39 static void 40 set_usb_driver(bool enabled) { 41 int fd = open("/sys/class/android_usb/android0/enable", O_WRONLY); 42 if (fd < 0) { 43 ui->Print("failed to open driver control: %s\n", strerror(errno)); 44 return; 45 } 46 if (write(fd, enabled ? "1" : "0", 1) < 0) { 47 ui->Print("failed to set driver control: %s\n", strerror(errno)); 48 } 49 if (close(fd) < 0) { 50 ui->Print("failed to close driver control: %s\n", strerror(errno)); 51 } 52 } 53 54 static void 55 stop_adbd() { 56 property_set("ctl.stop", "adbd"); 57 set_usb_driver(false); 58 } 59 60 61 static void 62 maybe_restart_adbd() { 63 char value[PROPERTY_VALUE_MAX+1]; 64 int len = property_get("ro.debuggable", value, NULL); 65 if (len == 1 && value[0] == '1') { 66 ui->Print("Restarting adbd...\n"); 67 set_usb_driver(true); 68 property_set("ctl.start", "adbd"); 69 } 70 } 71 72 int 73 apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) { 74 ui = ui_; 75 76 stop_adbd(); 77 set_usb_driver(true); 78 79 ui->Print("\n\nNow send the package you want to apply\n" 80 "to the device with \"adb sideload <filename>\"...\n"); 81 82 pid_t child; 83 if ((child = fork()) == 0) { 84 execl("/sbin/recovery", "recovery", "--adbd", NULL); 85 _exit(-1); 86 } 87 int status; 88 // TODO(dougz): there should be a way to cancel waiting for a 89 // package (by pushing some button combo on the device). For now 90 // you just have to 'adb sideload' a file that's not a valid 91 // package, like "/dev/null". 92 waitpid(child, &status, 0); 93 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 94 ui->Print("status %d\n", WEXITSTATUS(status)); 95 } 96 97 set_usb_driver(false); 98 maybe_restart_adbd(); 99 100 struct stat st; 101 if (stat(ADB_SIDELOAD_FILENAME, &st) != 0) { 102 if (errno == ENOENT) { 103 ui->Print("No package received.\n"); 104 } else { 105 ui->Print("Error reading package:\n %s\n", strerror(errno)); 106 } 107 return INSTALL_ERROR; 108 } 109 return install_package(ADB_SIDELOAD_FILENAME, wipe_cache, install_file); 110 } 111