console.cpp revision 5200c6670f041550c23821fec8e8e49b30ef6d29
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 <base/file.h> 22#include <base/logging.h> 23#include <base/strings.h> 24#include <cutils/sockets.h> 25 26#include "adb.h" 27#include "adb_client.h" 28 29// Return the console port of the currently connected emulator (if any) or -1 if 30// there is no emulator, and -2 if there is more than one. 31static int adb_get_emulator_console_port(const char* serial) { 32 if (serial) { 33 // The user specified a serial number; is it an emulator? 34 int port; 35 return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1; 36 } 37 38 // No specific device was given, so get the list of connected devices and 39 // search for emulators. If there's one, we'll take it. If there are more 40 // than one, that's an error. 41 std::string devices; 42 std::string error; 43 if (!adb_query("host:devices", &devices, &error)) { 44 fprintf(stderr, "error: no emulator connected: %s\n", error.c_str()); 45 return -1; 46 } 47 48 int port; 49 size_t emulator_count = 0; 50 for (const auto& device : android::base::Split(devices, "\n")) { 51 if (sscanf(device.c_str(), "emulator-%d", &port) == 1) { 52 if (++emulator_count > 1) { 53 fprintf( 54 stderr, "error: more than one emulator detected; use -s\n"); 55 return -1; 56 } 57 } 58 } 59 60 if (emulator_count == 0) { 61 fprintf(stderr, "error: no emulator detected\n"); 62 return -1; 63 } 64 65 return port; 66} 67 68static int connect_to_console(const char* serial) { 69 int port = adb_get_emulator_console_port(serial); 70 if (port == -1) { 71 return -1; 72 } 73 74 std::string error; 75 int fd = network_loopback_client(port, SOCK_STREAM, &error); 76 if (fd == -1) { 77 fprintf(stderr, "error: could not connect to TCP port %d: %s\n", port, 78 error.c_str()); 79 return -1; 80 } 81 return fd; 82} 83 84int adb_send_emulator_command(int argc, const char** argv, const char* serial) { 85 int fd = connect_to_console(serial); 86 if (fd == -1) { 87 return 1; 88 } 89 90 for (int i = 1; i < argc; i++) { 91 adb_write(fd, argv[i], strlen(argv[i])); 92 adb_write(fd, i == argc - 1 ? "\n" : " ", 1); 93 } 94 95 const char disconnect_command[] = "quit\n"; 96 if (adb_write(fd, disconnect_command, sizeof(disconnect_command) - 1) == -1) { 97 LOG(FATAL) << "Could not finalize emulator command"; 98 } 99 100 // Drain output that the emulator console has sent us to prevent a problem 101 // on Windows where if adb closes the socket without reading all the data, 102 // the emulator's next call to recv() will have an ECONNABORTED error, 103 // preventing the emulator from reading the command that adb has sent. 104 // https://code.google.com/p/android/issues/detail?id=21021 105 int result; 106 do { 107 char buf[BUFSIZ]; 108 result = adb_read(fd, buf, sizeof(buf)); 109 // Keep reading until zero bytes (EOF) or an error. If 'adb emu kill' 110 // is executed, the emulator calls exit() which causes adb to get 111 // ECONNRESET. Any other emu command is followed by the quit command 112 // that we sent above, and that causes the emulator to close the socket 113 // which should cause zero bytes (EOF) to be returned. 114 } while (result > 0); 115 116 adb_close(fd); 117 118 return 0; 119} 120