Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 1 | #define LOG_TAG "VNCFlinger" |
| 2 | #include <utils/Log.h> |
Steve Kondik | 95027ea | 2017-06-14 17:22:58 -0700 | [diff] [blame] | 3 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 4 | #include <fcntl.h> |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 5 | #include <fstream> |
| 6 | #include <signal.h> |
| 7 | #include <stdio.h> |
| 8 | #include <sys/types.h> |
| 9 | #include <unistd.h> |
Steve Kondik | 4679899 | 2017-06-15 23:58:54 -0700 | [diff] [blame] | 10 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 11 | #include "AndroidDesktop.h" |
Steve Kondik | 3db0747 | 2017-06-19 22:13:45 -0700 | [diff] [blame] | 12 | |
Steve Kondik | 6f9ab85 | 2017-07-09 21:30:20 -0700 | [diff] [blame] | 13 | #include <binder/IPCThreadState.h> |
| 14 | #include <binder/IServiceManager.h> |
| 15 | #include <binder/ProcessState.h> |
| 16 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 17 | #include <network/Socket.h> |
| 18 | #include <network/TcpSocket.h> |
| 19 | #include <rfb/Configuration.h> |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 20 | #include <rfb/LogWriter.h> |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 21 | #include <rfb/Logger_android.h> |
| 22 | #include <rfb/VNCServerST.h> |
| 23 | #include <rfb/util.h> |
Steve Kondik | 55db053 | 2017-06-12 11:27:18 -0700 | [diff] [blame] | 24 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 25 | using namespace vncflinger; |
Steve Kondik | 6f9ab85 | 2017-07-09 21:30:20 -0700 | [diff] [blame] | 26 | using namespace android; |
Steve Kondik | 55db053 | 2017-06-12 11:27:18 -0700 | [diff] [blame] | 27 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 28 | static char* gProgramName; |
| 29 | static bool gCaughtSignal = false; |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 30 | static std::string mPidFile; |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 31 | static rfb::IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol", 5900); |
Steve Kondik | 4679899 | 2017-06-15 23:58:54 -0700 | [diff] [blame] | 32 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 33 | static void printVersion(FILE* fp) { |
| 34 | fprintf(fp, "VNCFlinger 1.0"); |
Steve Kondik | 5c8655c | 2017-06-19 00:28:47 -0700 | [diff] [blame] | 35 | } |
| 36 | |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 37 | static void CleanupSignalHandler(int) |
| 38 | { |
| 39 | ALOGI("You killed me - cleaning up"); |
| 40 | if (mPidFile.length() != 0) { |
| 41 | remove(mPidFile.c_str()); |
| 42 | } |
| 43 | exit(1); |
| 44 | } |
| 45 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 46 | static void usage() { |
| 47 | printVersion(stderr); |
| 48 | fprintf(stderr, "\nUsage: %s [<parameters>]\n", gProgramName); |
| 49 | fprintf(stderr, " %s --version\n", gProgramName); |
| 50 | fprintf(stderr, |
| 51 | "\n" |
| 52 | "Parameters can be turned on with -<param> or off with -<param>=0\n" |
| 53 | "Parameters which take a value can be specified as " |
| 54 | "-<param> <value>\n" |
| 55 | "Other valid forms are <param>=<value> -<param>=<value> " |
| 56 | "--<param>=<value>\n" |
| 57 | "Parameter names are case-insensitive. The parameters are:\n\n"); |
| 58 | rfb::Configuration::listParams(79, 14); |
Steve Kondik | 5c8655c | 2017-06-19 00:28:47 -0700 | [diff] [blame] | 59 | exit(1); |
| 60 | } |
| 61 | |
Steve Kondik | 2c9d0cf | 2017-06-15 23:39:29 -0700 | [diff] [blame] | 62 | int main(int argc, char** argv) { |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 63 | rfb::initAndroidLogger(); |
| 64 | rfb::LogWriter::setLogParams("*:android:30"); |
Steve Kondik | 4679899 | 2017-06-15 23:58:54 -0700 | [diff] [blame] | 65 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 66 | gProgramName = argv[0]; |
Steve Kondik | 5c8655c | 2017-06-19 00:28:47 -0700 | [diff] [blame] | 67 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 68 | rfb::Configuration::enableServerParams(); |
Steve Kondik | 5c8655c | 2017-06-19 00:28:47 -0700 | [diff] [blame] | 69 | |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 70 | #ifdef SIGHUP |
| 71 | signal(SIGHUP, CleanupSignalHandler); |
| 72 | #endif |
| 73 | signal(SIGINT, CleanupSignalHandler); |
| 74 | signal(SIGTERM, CleanupSignalHandler); |
| 75 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 76 | for (int i = 1; i < argc; i++) { |
| 77 | if (rfb::Configuration::setParam(argv[i])) continue; |
Steve Kondik | 3db0747 | 2017-06-19 22:13:45 -0700 | [diff] [blame] | 78 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 79 | if (argv[i][0] == '-') { |
| 80 | if (i + 1 < argc) { |
| 81 | if (rfb::Configuration::setParam(&argv[i][1], argv[i + 1])) { |
| 82 | i++; |
| 83 | continue; |
| 84 | } |
| 85 | } |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 86 | if (strcmp(argv[i], "-pid") == 0) { |
| 87 | if (i + 1 < argc) { |
| 88 | mPidFile = std::string(argv[i + 1]); |
| 89 | i++; |
| 90 | continue; |
| 91 | } |
| 92 | } |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 93 | if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "-version") == 0 || |
| 94 | strcmp(argv[i], "--version") == 0) { |
| 95 | printVersion(stdout); |
| 96 | return 0; |
| 97 | } |
| 98 | usage(); |
| 99 | } |
| 100 | usage(); |
| 101 | } |
| 102 | |
Steve Kondik | 6f9ab85 | 2017-07-09 21:30:20 -0700 | [diff] [blame] | 103 | sp<ProcessState> self = ProcessState::self(); |
| 104 | self->startThreadPool(); |
| 105 | |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 106 | std::list<network::SocketListener*> listeners; |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 107 | int ret = 0; |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 108 | try { |
| 109 | sp<AndroidDesktop> desktop = new AndroidDesktop(); |
| 110 | rfb::VNCServerST server("vncflinger", desktop.get()); |
| 111 | network::createTcpListeners(&listeners, 0, (int)rfbport); |
| 112 | |
| 113 | int eventFd = desktop->getEventFd(); |
| 114 | fcntl(eventFd, F_SETFL, O_NONBLOCK); |
| 115 | |
| 116 | ALOGI("Listening on port %d", (int)rfbport); |
| 117 | |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 118 | if (mPidFile.length() != 0) { |
| 119 | // write a pid file |
| 120 | ALOGI("pid file %s", mPidFile.c_str()); |
| 121 | pid_t pid = getpid(); |
| 122 | std::ofstream outfile(mPidFile); |
| 123 | outfile << pid; |
| 124 | outfile.close(); |
| 125 | } |
| 126 | |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 127 | while (!gCaughtSignal) { |
| 128 | int wait_ms; |
| 129 | struct timeval tv; |
| 130 | fd_set rfds, wfds; |
| 131 | std::list<network::Socket*> sockets; |
| 132 | std::list<network::Socket*>::iterator i; |
| 133 | |
| 134 | FD_ZERO(&rfds); |
| 135 | FD_ZERO(&wfds); |
| 136 | |
| 137 | FD_SET(eventFd, &rfds); |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 138 | for (std::list<network::SocketListener*>::iterator i = listeners.begin(); |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 139 | i != listeners.end(); i++) |
| 140 | FD_SET((*i)->getFd(), &rfds); |
| 141 | |
| 142 | server.getSockets(&sockets); |
| 143 | int clients_connected = 0; |
| 144 | for (i = sockets.begin(); i != sockets.end(); i++) { |
| 145 | if ((*i)->isShutdown()) { |
| 146 | server.removeSocket(*i); |
| 147 | delete (*i); |
| 148 | } else { |
| 149 | FD_SET((*i)->getFd(), &rfds); |
| 150 | if ((*i)->outStream().bufferUsage() > 0) FD_SET((*i)->getFd(), &wfds); |
| 151 | clients_connected++; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | wait_ms = 0; |
| 156 | |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 157 | rfb::soonestTimeout(&wait_ms, rfb::Timer::checkTimeouts()); |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 158 | |
| 159 | tv.tv_sec = wait_ms / 1000; |
| 160 | tv.tv_usec = (wait_ms % 1000) * 1000; |
| 161 | |
| 162 | int n = select(FD_SETSIZE, &rfds, &wfds, 0, wait_ms ? &tv : NULL); |
| 163 | |
| 164 | if (n < 0) { |
| 165 | if (errno == EINTR) { |
| 166 | ALOGV("Interrupted select() system call"); |
| 167 | continue; |
| 168 | } else { |
| 169 | throw rdr::SystemException("select", errno); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // Accept new VNC connections |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 174 | for (std::list<network::SocketListener*>::iterator i = listeners.begin(); |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 175 | i != listeners.end(); i++) { |
| 176 | if (FD_ISSET((*i)->getFd(), &rfds)) { |
| 177 | network::Socket* sock = (*i)->accept(); |
| 178 | if (sock) { |
| 179 | sock->outStream().setBlocking(false); |
| 180 | server.addSocket(sock); |
| 181 | } else { |
| 182 | ALOGW("Client connection rejected"); |
| 183 | } |
| 184 | } |
| 185 | } |
| 186 | |
Steve Kondik | f19d142 | 2019-09-06 13:52:12 -0700 | [diff] [blame] | 187 | rfb::Timer::checkTimeouts(); |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 188 | |
| 189 | // Client list could have been changed. |
| 190 | server.getSockets(&sockets); |
| 191 | |
| 192 | // Nothing more to do if there are no client connections. |
| 193 | if (sockets.empty()) continue; |
| 194 | |
| 195 | // Process events on existing VNC connections |
| 196 | for (i = sockets.begin(); i != sockets.end(); i++) { |
| 197 | if (FD_ISSET((*i)->getFd(), &rfds)) server.processSocketReadEvent(*i); |
| 198 | if (FD_ISSET((*i)->getFd(), &wfds)) server.processSocketWriteEvent(*i); |
| 199 | } |
| 200 | |
| 201 | // Process events from the display |
| 202 | uint64_t eventVal; |
| 203 | int status = read(eventFd, &eventVal, sizeof(eventVal)); |
| 204 | if (status > 0 && eventVal > 0) { |
maxwen | 95dceef | 2019-12-07 12:00:17 +0100 | [diff] [blame] | 205 | //ALOGV("status=%d eventval=%lu", status, eventVal); |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 206 | desktop->processFrames(); |
| 207 | } |
| 208 | } |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 209 | ret = 0; |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 210 | } catch (rdr::Exception& e) { |
| 211 | ALOGE("%s", e.str()); |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 212 | ret = 1; |
Steve Kondik | 961b4cc | 2017-06-22 18:10:50 -0700 | [diff] [blame] | 213 | } |
maxwen | ec24ebe | 2019-12-07 13:36:32 +0100 | [diff] [blame] | 214 | ALOGI("Bye - cleaning up"); |
| 215 | if (mPidFile.length() != 0) { |
| 216 | remove(mPidFile.c_str()); |
| 217 | } |
| 218 | return ret; |
Steve Kondik | 55db053 | 2017-06-12 11:27:18 -0700 | [diff] [blame] | 219 | } |