diff options
Diffstat (limited to 'remoting/client')
-rw-r--r-- | remoting/client/client_util.cc | 89 | ||||
-rw-r--r-- | remoting/client/client_util.h | 8 | ||||
-rw-r--r-- | remoting/client/simple_client.cc | 2 | ||||
-rw-r--r-- | remoting/client/x11_client.cc | 141 |
4 files changed, 140 insertions, 100 deletions
diff --git a/remoting/client/client_util.cc b/remoting/client/client_util.cc index 2bc50c0..ddaee42 100644 --- a/remoting/client/client_util.cc +++ b/remoting/client/client_util.cc @@ -6,43 +6,88 @@ #include <iostream> +#include "base/logging.h" + namespace remoting { // Get host JID from command line arguments, or stdin if not specified. -bool GetLoginInfo(std::string* host_jid, +bool GetLoginInfo(int argc, char** argv, + std::string* host_jid, std::string* username, std::string* auth_token) { - std::cout << "Host JID: "; - std::cin >> *host_jid; - std::cin.ignore(); // Consume the leftover '\n' + bool found_host_jid = false; + bool found_jid = false; + bool found_auth_token = false; + + for (int i = 1; i < argc; i++) { + std::string arg = argv[i]; + if (arg == "--host_jid") { + if (++i >= argc) { + LOG(WARNING) << "Expected Host JID to follow --host_jid option" + << std::endl; + } else { + found_host_jid = true; + *host_jid = argv[i]; + } + } else if (arg == "--jid") { + if (++i >= argc) { + LOG(WARNING) << "Expected JID to follow --jid option" << std::endl; + } else { + found_jid = true; + *username = argv[i]; + } + } else if (arg == "--token") { + if (++i >= argc) { + LOG(WARNING) << "Expected Auth token to follow --token option" + << std::endl; + } else { + found_auth_token = true; + *auth_token = argv[i]; + } + } else { + LOG(WARNING) << "Unrecognized option: " << arg << std::endl; + } + } + if (!found_host_jid) { + std::cout << "Host JID: "; + std::cin >> *host_jid; + std::cin.ignore(); // Consume the leftover '\n' + } + + // Validate the chromoting host JID. if (host_jid->find("/chromoting") == std::string::npos) { std::cerr << "Error: Expected Host JID in format: <jid>/chromoting<id>" << std::endl; return false; } - // Get username (JID). - // Extract default JID from host_jid. - std::string default_username; - size_t jid_end = host_jid->find('/'); - if (jid_end != std::string::npos) { - default_username = host_jid->substr(0, jid_end); - } - std::cout << "JID [" << default_username << "]: "; - getline(std::cin, *username); - if (username->length() == 0) { - username->swap(default_username); + if (!found_jid) { + // Get username (JID). + // Extract default JID from host_jid. + std::string default_username; + size_t jid_end = host_jid->find('/'); + if (jid_end != std::string::npos) { + default_username = host_jid->substr(0, jid_end); + } + std::cout << "JID [" << default_username << "]: "; + getline(std::cin, *username); + if (username->length() == 0) { + username->swap(default_username); + } + if (username->length() == 0) { + std::cerr << "Error: Expected valid JID username" << std::endl; + return false; + } } - if (username->length() == 0) { - std::cerr << "Error: Expected valid JID username" << std::endl; - return 1; + + if (!found_auth_token) { + // Get authentication token. + std::cout << "Auth token: "; + getline(std::cin, *auth_token); + std::cout << std::endl; } - // Get authenication token (with console echo turned off). - std::cout << "Auth token: "; - getline(std::cin, *auth_token); - std::cout << std::endl; return true; } diff --git a/remoting/client/client_util.h b/remoting/client/client_util.h index 78ebcc0..44f3435 100644 --- a/remoting/client/client_util.h +++ b/remoting/client/client_util.h @@ -9,9 +9,11 @@ namespace remoting { -// Get the login info from the console and writes into |host_jid|, |username|, -// and |auth_token|. Return true if successful. -bool GetLoginInfo(std::string* host_jid, std::string* username, +// Get the login info from the cmdline args (or request from the console if +// not present) and write values into |host_jid|, |username| and |auth_token|. +// Return true if successful. +bool GetLoginInfo(int argc, char** argv, + std::string* host_jid, std::string* username, std::string* auth_token); } // namespace remoting diff --git a/remoting/client/simple_client.cc b/remoting/client/simple_client.cc index 7672ec3..85561bd 100644 --- a/remoting/client/simple_client.cc +++ b/remoting/client/simple_client.cc @@ -116,7 +116,7 @@ int main(int argc, char** argv) { std::string username; std::string auth_token; - if (!remoting::GetLoginInfo(&host_jid, &username, &auth_token)) { + if (!remoting::GetLoginInfo(argc, argv, &host_jid, &username, &auth_token)) { std::cerr << "Cannot get valid login info." << std::endl; return 1; } diff --git a/remoting/client/x11_client.cc b/remoting/client/x11_client.cc index 0e771a6..7531490 100644 --- a/remoting/client/x11_client.cc +++ b/remoting/client/x11_client.cc @@ -9,8 +9,11 @@ #include "base/at_exit.h" #include "base/message_loop.h" #include "base/stl_util-inl.h" -#include "remoting/client/jingle_host_connection.h" +#include "base/task.h" +#include "base/waitable_event.h" #include "remoting/client/client_util.h" +#include "remoting/client/host_connection.h" +#include "remoting/client/jingle_host_connection.h" #include "remoting/jingle_glue/jingle_thread.h" // Include Xlib at the end because it clashes with ClientMessage defined in @@ -20,19 +23,21 @@ #include "remoting/client/x11_view.h" #include <X11/Xlib.h> +using remoting::JingleHostConnection; +using remoting::JingleThread; + namespace remoting { class X11Client : public base::RefCountedThreadSafe<X11Client>, public HostConnection::HostEventCallback { public: - X11Client(std::string host_jid, std::string username, std::string auth_token) - : display_(NULL), + X11Client(MessageLoop* loop, base::WaitableEvent* client_done) + : message_loop_(loop), + client_done_(client_done), + display_(NULL), window_(0), width_(0), - height_(0), - host_jid_(host_jid), - username_(username), - auth_token_(auth_token) { + height_(0) { } virtual ~X11Client() { @@ -40,19 +45,6 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, DCHECK(!window_); } - // Starts the remoting client and the message loop. Returns only after - // the message loop has terminated. - void Run() { - // TODO(hclam): Fix the threading issue. - network_thread_.Start(); - message_loop_.PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoInitX11)); - message_loop_.PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoInitConnection)); - message_loop_.Run(); - network_thread_.Stop(); - } - //////////////////////////////////////////////////////////////////////////// // HostConnection::EventHandler implementations. virtual void HandleMessages(HostConnection* conn, @@ -60,18 +52,18 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, for (size_t i = 0; i < messages->size(); ++i) { HostMessage* msg = (*messages)[i]; if (msg->has_init_client()) { - message_loop_.PostTask( + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &X11Client::DoInitClient, msg)); } else if (msg->has_begin_update_stream()) { - message_loop_.PostTask( + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &X11Client::DoBeginUpdate, msg)); } else if (msg->has_update_stream_packet()) { - message_loop_.PostTask( + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &X11Client::DoHandleUpdate, msg)); } else if (msg->has_end_update_stream()) { - message_loop_.PostTask( + message_loop_->PostTask( FROM_HERE, NewRunnableMethod(this, &X11Client::DoEndUpdate, msg)); } else { NOTREACHED() << "Unknown message received"; @@ -82,25 +74,29 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, } virtual void OnConnectionOpened(HostConnection* conn) { - std::cout << "Connection establised." << std::endl; + std::cout << "Connection established." << std::endl; } virtual void OnConnectionClosed(HostConnection* conn) { std::cout << "Connection closed." << std::endl; - Exit(); + client_done_->Signal(); } virtual void OnConnectionFailed(HostConnection* conn) { std::cout << "Conection failed." << std::endl; - Exit(); + client_done_->Signal(); + } + + void InitX11() { + message_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &X11Client::DoInitX11)); } - private: void DoInitX11() { display_ = XOpenDisplay(NULL); if (!display_) { std::cout << "Error - cannot open display" << std::endl; - Exit(); + client_done_->Signal(); } // Get properties of the screen. @@ -119,15 +115,9 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, XMapWindow(display_, window_); } - void DoInitConnection() { - // If the initialization of X11 has failed then return directly. - if (!display_) - return; - - // Creates a HostConnection object and connection to the host. - LOG(INFO) << "Connecting..."; - connection_.reset(new JingleHostConnection(&network_thread_, this)); - connection_->Connect(username_, auth_token_, host_jid_); + void DestroyX11() { + message_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &X11Client::DoDestroyX11)); } void DoDestroyX11() { @@ -140,27 +130,10 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, } } - void DoDisconnect() { - if (connection_.get()) - connection_->Disconnect(); - } - - void Exit() { - // Disconnect the jingle channel and client. - message_loop_.PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoDisconnect)); - - // Post a task to shutdown X11. - message_loop_.PostTask(FROM_HERE, - NewRunnableMethod(this, &X11Client::DoDestroyX11)); - - // Quit the current message loop. - message_loop_.PostTask(FROM_HERE, new MessageLoop::QuitTask()); - } - + private: // This method is executed on the main loop. void DoInitClient(HostMessage* msg) { - DCHECK_EQ(&message_loop_, MessageLoop::current()); + DCHECK_EQ(message_loop_, MessageLoop::current()); DCHECK(msg->has_init_client()); scoped_ptr<HostMessage> deleter(msg); @@ -179,28 +152,28 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, // The following methods are executed on the same thread as libjingle. void DoBeginUpdate(HostMessage* msg) { - DCHECK_EQ(&message_loop_, MessageLoop::current()); + DCHECK_EQ(message_loop_, MessageLoop::current()); DCHECK(msg->has_begin_update_stream()); view_->HandleBeginUpdateStream(msg); } void DoHandleUpdate(HostMessage* msg) { - DCHECK_EQ(&message_loop_, MessageLoop::current()); + DCHECK_EQ(message_loop_, MessageLoop::current()); DCHECK(msg->has_update_stream_packet()); view_->HandleUpdateStreamPacket(msg); } void DoEndUpdate(HostMessage* msg) { - DCHECK_EQ(&message_loop_, MessageLoop::current()); + DCHECK_EQ(message_loop_, MessageLoop::current()); DCHECK(msg->has_end_update_stream()); view_->HandleEndUpdateStream(msg); } void DoProcessX11Events() { - DCHECK_EQ(&message_loop_, MessageLoop::current()); + DCHECK_EQ(message_loop_, MessageLoop::current()); if (XPending(display_)) { XEvent e; XNextEvent(display_, &e); @@ -223,12 +196,15 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, void ScheduleX11EventHandler() { // Schedule a delayed task to process X11 events in 10ms. static const int kProcessEventsInterval = 10; - message_loop_.PostDelayedTask( + message_loop_->PostDelayedTask( FROM_HERE, NewRunnableMethod(this, &X11Client::DoProcessX11Events), kProcessEventsInterval); } + MessageLoop* message_loop_; + base::WaitableEvent* client_done_; + // Members used for display. Display* display_; Window window_; @@ -238,30 +214,47 @@ class X11Client : public base::RefCountedThreadSafe<X11Client>, int width_; int height_; - std::string host_jid_; - std::string username_; - std::string auth_token_; - scoped_ptr<HostConnection> connection_; scoped_refptr<ChromotingView> view_; - JingleThread network_thread_; - MessageLoop message_loop_; - DISALLOW_COPY_AND_ASSIGN(X11Client); }; } // namespace remoting -int main() { +int main(int argc, char** argv) { base::AtExitManager at_exit; - std::string host_jid, username, auth_token; + std::string host_jid; + std::string username; + std::string auth_token; - if (!remoting::GetLoginInfo(&host_jid, &username, &auth_token)) { + if (!remoting::GetLoginInfo(argc, argv, &host_jid, &username, &auth_token)) { std::cout << "Cannot obtain login info" << std::endl; return 1; } + JingleThread network_thread; + network_thread.Start(); + + base::WaitableEvent client_done(false, false); scoped_refptr<remoting::X11Client> client = - new remoting::X11Client(host_jid, username, auth_token); - client->Run(); + new remoting::X11Client(network_thread.message_loop(), &client_done); + scoped_refptr<JingleHostConnection> connection = + new JingleHostConnection(&network_thread, client); + connection->Connect(username, auth_token, host_jid); + + client->InitX11(); + + // Wait until the main loop is done. + client_done.Wait(); + + connection->Disconnect(); + + client->DestroyX11(); + + // Quit the current message loop. + network_thread.message_loop()->PostTask(FROM_HERE, + new MessageLoop::QuitTask()); + network_thread.Stop(); + + return 0; } |