blob: 2b8a0aa8b4d34b4e53e7dc29e0c4337556e335fd [file] [log] [blame]
Steve Kondik961b4cc2017-06-22 18:10:50 -07001#define LOG_TAG "VNCFlinger"
2#include <utils/Log.h>
Steve Kondik95027ea2017-06-14 17:22:58 -07003
Steve Kondik961b4cc2017-06-22 18:10:50 -07004#include <fcntl.h>
maxwenec24ebe2019-12-07 13:36:32 +01005#include <fstream>
6#include <signal.h>
7#include <stdio.h>
8#include <sys/types.h>
9#include <unistd.h>
Steve Kondik46798992017-06-15 23:58:54 -070010
Steve Kondik961b4cc2017-06-22 18:10:50 -070011#include "AndroidDesktop.h"
Steve Kondik3db07472017-06-19 22:13:45 -070012
Steve Kondik6f9ab852017-07-09 21:30:20 -070013#include <binder/IPCThreadState.h>
14#include <binder/IServiceManager.h>
15#include <binder/ProcessState.h>
16
Steve Kondik961b4cc2017-06-22 18:10:50 -070017#include <network/Socket.h>
18#include <network/TcpSocket.h>
19#include <rfb/Configuration.h>
Steve Kondikf19d1422019-09-06 13:52:12 -070020#include <rfb/LogWriter.h>
Steve Kondik961b4cc2017-06-22 18:10:50 -070021#include <rfb/Logger_android.h>
22#include <rfb/VNCServerST.h>
23#include <rfb/util.h>
Steve Kondik55db0532017-06-12 11:27:18 -070024
Steve Kondik961b4cc2017-06-22 18:10:50 -070025using namespace vncflinger;
Steve Kondik6f9ab852017-07-09 21:30:20 -070026using namespace android;
Steve Kondik55db0532017-06-12 11:27:18 -070027
Steve Kondik961b4cc2017-06-22 18:10:50 -070028static char* gProgramName;
29static bool gCaughtSignal = false;
maxwenec24ebe2019-12-07 13:36:32 +010030static std::string mPidFile;
Steve Kondik961b4cc2017-06-22 18:10:50 -070031static rfb::IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol", 5900);
Steve Kondik46798992017-06-15 23:58:54 -070032
Steve Kondik961b4cc2017-06-22 18:10:50 -070033static void printVersion(FILE* fp) {
34 fprintf(fp, "VNCFlinger 1.0");
Steve Kondik5c8655c2017-06-19 00:28:47 -070035}
36
maxwenec24ebe2019-12-07 13:36:32 +010037static 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 Kondik961b4cc2017-06-22 18:10:50 -070046static 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 Kondik5c8655c2017-06-19 00:28:47 -070059 exit(1);
60}
61
Steve Kondik2c9d0cf2017-06-15 23:39:29 -070062int main(int argc, char** argv) {
Steve Kondik961b4cc2017-06-22 18:10:50 -070063 rfb::initAndroidLogger();
64 rfb::LogWriter::setLogParams("*:android:30");
Steve Kondik46798992017-06-15 23:58:54 -070065
Steve Kondik961b4cc2017-06-22 18:10:50 -070066 gProgramName = argv[0];
Steve Kondik5c8655c2017-06-19 00:28:47 -070067
Steve Kondik961b4cc2017-06-22 18:10:50 -070068 rfb::Configuration::enableServerParams();
Steve Kondik5c8655c2017-06-19 00:28:47 -070069
maxwenec24ebe2019-12-07 13:36:32 +010070#ifdef SIGHUP
71 signal(SIGHUP, CleanupSignalHandler);
72#endif
73 signal(SIGINT, CleanupSignalHandler);
74 signal(SIGTERM, CleanupSignalHandler);
75
Steve Kondik961b4cc2017-06-22 18:10:50 -070076 for (int i = 1; i < argc; i++) {
77 if (rfb::Configuration::setParam(argv[i])) continue;
Steve Kondik3db07472017-06-19 22:13:45 -070078
Steve Kondik961b4cc2017-06-22 18:10:50 -070079 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 }
maxwenec24ebe2019-12-07 13:36:32 +010086 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 Kondik961b4cc2017-06-22 18:10:50 -070093 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 Kondik6f9ab852017-07-09 21:30:20 -0700103 sp<ProcessState> self = ProcessState::self();
104 self->startThreadPool();
105
Steve Kondikf19d1422019-09-06 13:52:12 -0700106 std::list<network::SocketListener*> listeners;
maxwenec24ebe2019-12-07 13:36:32 +0100107 int ret = 0;
Steve Kondik961b4cc2017-06-22 18:10:50 -0700108 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
maxwenec24ebe2019-12-07 13:36:32 +0100118 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 Kondik961b4cc2017-06-22 18:10:50 -0700127 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 Kondikf19d1422019-09-06 13:52:12 -0700138 for (std::list<network::SocketListener*>::iterator i = listeners.begin();
Steve Kondik961b4cc2017-06-22 18:10:50 -0700139 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 Kondikf19d1422019-09-06 13:52:12 -0700157 rfb::soonestTimeout(&wait_ms, rfb::Timer::checkTimeouts());
Steve Kondik961b4cc2017-06-22 18:10:50 -0700158
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 Kondikf19d1422019-09-06 13:52:12 -0700174 for (std::list<network::SocketListener*>::iterator i = listeners.begin();
Steve Kondik961b4cc2017-06-22 18:10:50 -0700175 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 Kondikf19d1422019-09-06 13:52:12 -0700187 rfb::Timer::checkTimeouts();
Steve Kondik961b4cc2017-06-22 18:10:50 -0700188
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) {
maxwen95dceef2019-12-07 12:00:17 +0100205 //ALOGV("status=%d eventval=%lu", status, eventVal);
Steve Kondik961b4cc2017-06-22 18:10:50 -0700206 desktop->processFrames();
207 }
208 }
maxwenec24ebe2019-12-07 13:36:32 +0100209 ret = 0;
Steve Kondik961b4cc2017-06-22 18:10:50 -0700210 } catch (rdr::Exception& e) {
211 ALOGE("%s", e.str());
maxwenec24ebe2019-12-07 13:36:32 +0100212 ret = 1;
Steve Kondik961b4cc2017-06-22 18:10:50 -0700213 }
maxwenec24ebe2019-12-07 13:36:32 +0100214 ALOGI("Bye - cleaning up");
215 if (mPidFile.length() != 0) {
216 remove(mPidFile.c_str());
217 }
218 return ret;
Steve Kondik55db0532017-06-12 11:27:18 -0700219}