xref: /aosp_15_r20/external/webrtc/examples/peerconnection/client/main.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 // clang-format off
12 // clang formating would change include order.
13 #include <windows.h>
14 #include <shellapi.h>  // must come after windows.h
15 // clang-format on
16 
17 #include <string>
18 #include <vector>
19 
20 #include "absl/flags/parse.h"
21 #include "examples/peerconnection/client/conductor.h"
22 #include "examples/peerconnection/client/flag_defs.h"
23 #include "examples/peerconnection/client/main_wnd.h"
24 #include "examples/peerconnection/client/peer_connection_client.h"
25 #include "rtc_base/checks.h"
26 #include "rtc_base/ssl_adapter.h"
27 #include "rtc_base/string_utils.h"  // For ToUtf8
28 #include "rtc_base/win32_socket_init.h"
29 #include "system_wrappers/include/field_trial.h"
30 #include "test/field_trial.h"
31 
32 namespace {
33 // A helper class to translate Windows command line arguments into UTF8,
34 // which then allows us to just pass them to the flags system.
35 // This encapsulates all the work of getting the command line and translating
36 // it to an array of 8-bit strings; all you have to do is create one of these,
37 // and then call argc() and argv().
38 class WindowsCommandLineArguments {
39  public:
40   WindowsCommandLineArguments();
41 
42   WindowsCommandLineArguments(const WindowsCommandLineArguments&) = delete;
43   WindowsCommandLineArguments& operator=(WindowsCommandLineArguments&) = delete;
44 
argc()45   int argc() { return argv_.size(); }
argv()46   char** argv() { return argv_.data(); }
47 
48  private:
49   // Owned argument strings.
50   std::vector<std::string> args_;
51   // Pointers, to get layout compatible with char** argv.
52   std::vector<char*> argv_;
53 };
54 
WindowsCommandLineArguments()55 WindowsCommandLineArguments::WindowsCommandLineArguments() {
56   // start by getting the command line.
57   LPCWSTR command_line = ::GetCommandLineW();
58   // now, convert it to a list of wide char strings.
59   int argc;
60   LPWSTR* wide_argv = ::CommandLineToArgvW(command_line, &argc);
61 
62   // iterate over the returned wide strings;
63   for (int i = 0; i < argc; ++i) {
64     args_.push_back(rtc::ToUtf8(wide_argv[i], wcslen(wide_argv[i])));
65     // make sure the argv array points to the string data.
66     argv_.push_back(const_cast<char*>(args_.back().c_str()));
67   }
68   LocalFree(wide_argv);
69 }
70 
71 }  // namespace
wWinMain(HINSTANCE instance,HINSTANCE prev_instance,wchar_t * cmd_line,int cmd_show)72 int PASCAL wWinMain(HINSTANCE instance,
73                     HINSTANCE prev_instance,
74                     wchar_t* cmd_line,
75                     int cmd_show) {
76   rtc::WinsockInitializer winsock_init;
77   rtc::PhysicalSocketServer ss;
78   rtc::AutoSocketServerThread main_thread(&ss);
79 
80   WindowsCommandLineArguments win_args;
81   int argc = win_args.argc();
82   char** argv = win_args.argv();
83 
84   absl::ParseCommandLine(argc, argv);
85 
86   // InitFieldTrialsFromString stores the char*, so the char array must outlive
87   // the application.
88   const std::string forced_field_trials =
89       absl::GetFlag(FLAGS_force_fieldtrials);
90   webrtc::field_trial::InitFieldTrialsFromString(forced_field_trials.c_str());
91 
92   // Abort if the user specifies a port that is outside the allowed
93   // range [1, 65535].
94   if ((absl::GetFlag(FLAGS_port) < 1) || (absl::GetFlag(FLAGS_port) > 65535)) {
95     printf("Error: %i is not a valid port.\n", absl::GetFlag(FLAGS_port));
96     return -1;
97   }
98 
99   const std::string server = absl::GetFlag(FLAGS_server);
100   MainWnd wnd(server.c_str(), absl::GetFlag(FLAGS_port),
101               absl::GetFlag(FLAGS_autoconnect), absl::GetFlag(FLAGS_autocall));
102   if (!wnd.Create()) {
103     RTC_DCHECK_NOTREACHED();
104     return -1;
105   }
106 
107   rtc::InitializeSSL();
108   PeerConnectionClient client;
109   auto conductor = rtc::make_ref_counted<Conductor>(&client, &wnd);
110 
111   // Main loop.
112   MSG msg;
113   BOOL gm;
114   while ((gm = ::GetMessage(&msg, NULL, 0, 0)) != 0 && gm != -1) {
115     if (!wnd.PreTranslateMessage(&msg)) {
116       ::TranslateMessage(&msg);
117       ::DispatchMessage(&msg);
118     }
119   }
120 
121   if (conductor->connection_active() || client.is_connected()) {
122     while ((conductor->connection_active() || client.is_connected()) &&
123            (gm = ::GetMessage(&msg, NULL, 0, 0)) != 0 && gm != -1) {
124       if (!wnd.PreTranslateMessage(&msg)) {
125         ::TranslateMessage(&msg);
126         ::DispatchMessage(&msg);
127       }
128     }
129   }
130 
131   rtc::CleanupSSL();
132   return 0;
133 }
134