1 /* 2 * Copyright (C) 2015 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 "sysdeps.h" 18 19 #include <stdio.h> 20 21 #include <android-base/file.h> 22 #include <android-base/logging.h> 23 #include <android-base/strings.h> 24 #include <cutils/sockets.h> 25 26 #include "adb.h" 27 #include "adb_client.h" 28 #include "adb_io.h" 29 #include "adb_utils.h" 30 31 // Return the console authentication command for the emulator, if needed 32 static std::string adb_construct_auth_command() { 33 static const char auth_token_filename[] = ".emulator_console_auth_token"; 34 35 std::string auth_token_path = adb_get_homedir_path(false); 36 auth_token_path += OS_PATH_SEPARATOR; 37 auth_token_path += auth_token_filename; 38 39 // read the token 40 std::string token; 41 if (!android::base::ReadFileToString(auth_token_path, &token) 42 || token.empty()) { 43 // we either can't read the file, or it doesn't exist, or it's empty - 44 // either way we won't add any authentication command. 45 return {}; 46 } 47 48 // now construct and return the actual command: "auth <token>\n" 49 std::string command = "auth "; 50 command += token; 51 command += '\n'; 52 return command; 53 } 54 55 // Return the console port of the currently connected emulator (if any) or -1 if 56 // there is no emulator, and -2 if there is more than one. 57 static int adb_get_emulator_console_port(const char* serial) { 58 if (serial) { 59 // The user specified a serial number; is it an emulator? 60 int port; 61 return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1; 62 } 63 64 // No specific device was given, so get the list of connected devices and 65 // search for emulators. If there's one, we'll take it. If there are more 66 // than one, that's an error. 67 std::string devices; 68 std::string error; 69 if (!adb_query("host:devices", &devices, &error)) { 70 fprintf(stderr, "error: no emulator connected: %s\n", error.c_str()); 71 return -1; 72 } 73 74 int port; 75 size_t emulator_count = 0; 76 for (const auto& device : android::base::Split(devices, "\n")) { 77 if (sscanf(device.c_str(), "emulator-%d", &port) == 1) { 78 if (++emulator_count > 1) { 79 fprintf( 80 stderr, "error: more than one emulator detected; use -s\n"); 81 return -1; 82 } 83 } 84 } 85 86 if (emulator_count == 0) { 87 fprintf(stderr, "error: no emulator detected\n"); 88 return -1; 89 } 90 91 return port; 92 } 93 94 static int connect_to_console(const char* serial) { 95 int port = adb_get_emulator_console_port(serial); 96 if (port == -1) { 97 return -1; 98 } 99 100 std::string error; 101 int fd = network_loopback_client(port, SOCK_STREAM, &error); 102 if (fd == -1) { 103 fprintf(stderr, "error: could not connect to TCP port %d: %s\n", port, 104 error.c_str()); 105 return -1; 106 } 107 return fd; 108 } 109 110 int adb_send_emulator_command(int argc, const char** argv, const char* serial) { 111 int fd = connect_to_console(serial); 112 if (fd == -1) { 113 return 1; 114 } 115 116 std::string commands = adb_construct_auth_command(); 117 118 for (int i = 1; i < argc; i++) { 119 commands.append(argv[i]); 120 commands.push_back(i == argc - 1 ? '\n' : ' '); 121 } 122 123 commands.append("quit\n"); 124 125 if (!WriteFdExactly(fd, commands)) { 126 fprintf(stderr, "error: cannot write to emulator: %s\n", 127 strerror(errno)); 128 adb_close(fd); 129 return 1; 130 } 131 132 // Drain output that the emulator console has sent us to prevent a problem 133 // on Windows where if adb closes the socket without reading all the data, 134 // the emulator's next call to recv() will have an ECONNABORTED error, 135 // preventing the emulator from reading the command that adb has sent. 136 // https://code.google.com/p/android/issues/detail?id=21021 137 int result; 138 do { 139 char buf[BUFSIZ]; 140 result = adb_read(fd, buf, sizeof(buf)); 141 // Keep reading until zero bytes (orderly/graceful shutdown) or an 142 // error. If 'adb emu kill' is executed, the emulator calls exit() with 143 // the socket open (and shutdown(SD_SEND) was not called), which causes 144 // Windows to send a TCP RST segment which causes adb to get ECONNRESET. 145 // Any other emu command is followed by the quit command that we 146 // appended above, and that causes the emulator to close the socket 147 // which should cause zero bytes (orderly/graceful shutdown) to be 148 // returned. 149 } while (result > 0); 150 151 adb_close(fd); 152 153 return 0; 154 } 155