Home | History | Annotate | Download | only in adb
      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();
     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