1 /*
2 * Copyright (C) 2016 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 #ifndef COMMANDLINE_H
18 #define COMMANDLINE_H
19
20 #include <android-base/strings.h>
21
22 #include "adb.h"
23 #include "adb_client.h"
24 #include "adb_unique_fd.h"
25
26 // Callback used to handle the standard streams (stdout and stderr) sent by the
27 // device's upon receiving a command.
28 //
29 class StandardStreamsCallbackInterface {
30 public:
StandardStreamsCallbackInterface()31 StandardStreamsCallbackInterface() {
32 }
33 // Handles the stdout output from devices supporting the Shell protocol.
34 virtual void OnStdout(const char* buffer, int length) = 0;
35
36 // Handles the stderr output from devices supporting the Shell protocol.
37 virtual void OnStderr(const char* buffer, int length) = 0;
38
39 // Indicates the communication is finished and returns the appropriate error
40 // code.
41 //
42 // |status| has the status code returning by the underlying communication
43 // channels
44 virtual int Done(int status) = 0;
45
46 protected:
OnStream(std::string * string,FILE * stream,const char * buffer,int length)47 static void OnStream(std::string* string, FILE* stream, const char* buffer, int length) {
48 if (string != nullptr) {
49 string->append(buffer, length);
50 } else {
51 fwrite(buffer, 1, length, stream);
52 fflush(stream);
53 }
54 }
55
56 private:
57 DISALLOW_COPY_AND_ASSIGN(StandardStreamsCallbackInterface);
58 };
59
60 // Default implementation that redirects the streams to the equilavent host
61 // stream or to a string
62 // passed to the constructor.
63 class DefaultStandardStreamsCallback : public StandardStreamsCallbackInterface {
64 public:
65 // If |stdout_str| is non-null, OnStdout will append to it.
66 // If |stderr_str| is non-null, OnStderr will append to it.
DefaultStandardStreamsCallback(std::string * stdout_str,std::string * stderr_str)67 DefaultStandardStreamsCallback(std::string* stdout_str, std::string* stderr_str)
68 : stdout_str_(stdout_str), stderr_str_(stderr_str) {
69 }
70
OnStdout(const char * buffer,int length)71 void OnStdout(const char* buffer, int length) {
72 OnStream(stdout_str_, stdout, buffer, length);
73 }
74
OnStderr(const char * buffer,int length)75 void OnStderr(const char* buffer, int length) {
76 OnStream(stderr_str_, stderr, buffer, length);
77 }
78
Done(int status)79 int Done(int status) {
80 return status;
81 }
82
83 private:
84 std::string* stdout_str_;
85 std::string* stderr_str_;
86
87 DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
88 };
89
90 class SilentStandardStreamsCallbackInterface : public StandardStreamsCallbackInterface {
91 public:
92 SilentStandardStreamsCallbackInterface() = default;
OnStdout(const char *,int)93 void OnStdout(const char*, int) override final {}
OnStderr(const char *,int)94 void OnStderr(const char*, int) override final {}
Done(int status)95 int Done(int status) override final { return status; }
96 };
97
98 // Singleton.
99 extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
100
101 int adb_commandline(int argc, const char** argv);
102
103 bool copy_to_file(int inFd, int outFd);
104
105 // Connects to the device "shell" service with |command| and prints the
106 // resulting output.
107 // if |callback| is non-null, stdout/stderr output will be handled by it.
108 int send_shell_command(
109 const std::string& command, bool disable_shell_protocol = false,
110 StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
111
112 // Reads from |fd| and prints received data. If |use_shell_protocol| is true
113 // this expects that incoming data will use the shell protocol, in which case
114 // stdout/stderr are routed independently and the remote exit code will be
115 // returned.
116 // if |callback| is non-null, stdout/stderr output will be handled by it.
117 int read_and_dump(borrowed_fd fd, bool use_shell_protocol = false,
118 StandardStreamsCallbackInterface* callback = &DEFAULT_STANDARD_STREAMS_CALLBACK);
119
120 // Connects to the device "abb" service with |command| and returns the fd.
121 template <typename ContainerT>
send_abb_exec_command(const ContainerT & command_args,std::string * error)122 unique_fd send_abb_exec_command(const ContainerT& command_args, std::string* error) {
123 std::string service_string = "abb_exec:" + android::base::Join(command_args, ABB_ARG_DELIMETER);
124
125 unique_fd fd(adb_connect(service_string, error));
126 if (fd < 0) {
127 fprintf(stderr, "adb: failed to run abb_exec. Error: %s\n", error->c_str());
128 return unique_fd{};
129 }
130 return fd;
131 }
132
133 #endif // COMMANDLINE_H
134