Adding WinUWP compilation support to WebRTC.
Windows UWP allows an application to be built that targets
across all Windows 10 based systems and the Windows store.
Change-Id: I69694bb7e83fb01ad6db2438b065b55738cf01fd
Bug: webrtc:10046
Reviewed-on: https://webrtc-review.googlesource.com/c/110570
Commit-Queue: Patrik Höglund <phoglund@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Patrik Höglund <phoglund@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25814}
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 4ed07af..d87d5d6 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -47,12 +47,14 @@
if (is_linux || is_win) {
deps += [
- ":peerconnection_client",
":peerconnection_server",
":relayserver",
":stunserver",
":turnserver",
]
+ if (current_os != "winuwp") {
+ deps += [ ":peerconnection_client" ]
+ }
}
if (is_android || is_win) {
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 75c4397..c88815f 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -870,11 +870,13 @@
]
if (is_win) {
- sources += [
- "win32socketinit.h",
- "win32socketserver.cc",
- "win32socketserver.h",
- ]
+ sources += [ "win32socketinit.h" ]
+ if (current_os != "winuwp") {
+ sources += [
+ "win32socketserver.cc",
+ "win32socketserver.h",
+ ]
+ }
}
} # !build_with_chromium
diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc
index 7926f88..4fa5f41 100644
--- a/rtc_base/httpcommon.cc
+++ b/rtc_base/httpcommon.cc
@@ -38,7 +38,7 @@
namespace rtc {
namespace {
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
///////////////////////////////////////////////////////////////////////////////
// ConstantToLabel can be used to easily generate string names from constant
// values. This can be useful for logging descriptive names of error messages.
@@ -113,7 +113,7 @@
LASTLABEL};
#undef KLABEL
#undef LASTLABEL
-#endif // defined(WEBRTC_WIN)
+#endif // defined(WEBRTC_WIN) && !defined(WINUWP)
typedef std::pair<std::string, std::string> HttpAttribute;
typedef std::vector<HttpAttribute> HttpAttributeList;
@@ -225,7 +225,7 @@
return result;
}
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
struct NegotiateAuthContext : public HttpAuthContext {
CredHandle cred;
CtxtHandle ctx;
@@ -244,7 +244,7 @@
FreeCredentialsHandle(&cred);
}
};
-#endif // WEBRTC_WIN
+#endif // defined(WEBRTC_WIN) && !defined(WINUWP)
} // anonymous namespace
@@ -359,7 +359,7 @@
return HAR_RESPONSE;
}
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
#if 1
bool want_negotiate = absl::EqualsIgnoreCase(auth_method, "negotiate");
bool want_ntlm = absl::EqualsIgnoreCase(auth_method, "ntlm");
@@ -544,7 +544,7 @@
return HAR_RESPONSE;
}
#endif
-#endif // WEBRTC_WIN
+#endif // defined(WEBRTC_WIN) && !defined(WINUWP)
return HAR_IGNORE;
}
diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
index bb4fbfa..8d6afbc 100644
--- a/rtc_base/logging.cc
+++ b/rtc_base/logging.cc
@@ -327,7 +327,7 @@
}
}
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
if ((LS_NONE != debug_level) && !::IsDebuggerPresent()) {
// First, attempt to attach to our parent's console... so if you invoke
// from the command line, we'll see the output there. Otherwise, create
@@ -336,7 +336,7 @@
if (!AttachConsole(ATTACH_PARENT_PROCESS))
::AllocConsole();
}
-#endif // WEBRTC_WIN
+#endif // defined(WEBRTC_WIN) && !defined(WINUWP)
LogToDebug(debug_level);
}
diff --git a/rtc_base/nethelpers.cc b/rtc_base/nethelpers.cc
index 81cd1af..1bba3b4 100644
--- a/rtc_base/nethelpers.cc
+++ b/rtc_base/nethelpers.cc
@@ -161,7 +161,10 @@
}
bool HasIPv6Enabled() {
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+ // WinUWP always has IPv6 capability.
+ return true;
+#elif defined(WEBRTC_WIN)
if (IsWindowsVistaOrLater()) {
return true;
}
diff --git a/rtc_base/socketadapters.cc b/rtc_base/socketadapters.cc
index 9451928..3bac17b 100644
--- a/rtc_base/socketadapters.cc
+++ b/rtc_base/socketadapters.cc
@@ -427,7 +427,7 @@
// std::string msg("Please report the following information to
// foo@bar.com:\r\nUnknown methods: ");
msg.append(unknown_mechanisms_);
-#if defined(WEBRTC_WIN)
+#if defined(WEBRTC_WIN) && !defined(WINUWP)
MessageBoxA(0, msg.c_str(), "Oops!", MB_OK);
#endif
#if defined(WEBRTC_POSIX)
diff --git a/rtc_base/synchronization/rw_lock_win.cc b/rtc_base/synchronization/rw_lock_win.cc
index 44cc0a7..a0d24a3 100644
--- a/rtc_base/synchronization/rw_lock_win.cc
+++ b/rtc_base/synchronization/rw_lock_win.cc
@@ -14,23 +14,19 @@
namespace webrtc {
-static bool native_rw_locks_supported = false;
-static bool module_load_attempted = false;
-static HMODULE library = NULL;
+typedef void(WINAPI* PInitializeSRWLock)(PSRWLOCK);
-typedef void(WINAPI* InitializeSRWLock)(PSRWLOCK);
+typedef void(WINAPI* PAcquireSRWLockExclusive)(PSRWLOCK);
+typedef void(WINAPI* PReleaseSRWLockExclusive)(PSRWLOCK);
-typedef void(WINAPI* AcquireSRWLockExclusive)(PSRWLOCK);
-typedef void(WINAPI* ReleaseSRWLockExclusive)(PSRWLOCK);
+typedef void(WINAPI* PAcquireSRWLockShared)(PSRWLOCK);
+typedef void(WINAPI* PReleaseSRWLockShared)(PSRWLOCK);
-typedef void(WINAPI* AcquireSRWLockShared)(PSRWLOCK);
-typedef void(WINAPI* ReleaseSRWLockShared)(PSRWLOCK);
-
-InitializeSRWLock initialize_srw_lock;
-AcquireSRWLockExclusive acquire_srw_lock_exclusive;
-AcquireSRWLockShared acquire_srw_lock_shared;
-ReleaseSRWLockShared release_srw_lock_shared;
-ReleaseSRWLockExclusive release_srw_lock_exclusive;
+PInitializeSRWLock initialize_srw_lock;
+PAcquireSRWLockExclusive acquire_srw_lock_exclusive;
+PAcquireSRWLockShared acquire_srw_lock_shared;
+PReleaseSRWLockShared release_srw_lock_shared;
+PReleaseSRWLockExclusive release_srw_lock_exclusive;
RWLockWin::RWLockWin() {
initialize_srw_lock(&lock_);
@@ -60,28 +56,31 @@
}
bool RWLockWin::LoadModule() {
+ static bool module_load_attempted = false;
+ static bool native_rw_locks_supported = false;
if (module_load_attempted) {
return native_rw_locks_supported;
}
module_load_attempted = true;
+#if !defined(WINUWP)
// Use native implementation if supported (i.e Vista+)
- library = LoadLibrary(TEXT("Kernel32.dll"));
+ static HMODULE library = LoadLibrary(TEXT("Kernel32.dll"));
if (!library) {
return false;
}
RTC_LOG(LS_VERBOSE) << "Loaded Kernel.dll";
initialize_srw_lock =
- (InitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
+ (PInitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
- acquire_srw_lock_exclusive = (AcquireSRWLockExclusive)GetProcAddress(
+ acquire_srw_lock_exclusive = (PAcquireSRWLockExclusive)GetProcAddress(
library, "AcquireSRWLockExclusive");
- release_srw_lock_exclusive = (ReleaseSRWLockExclusive)GetProcAddress(
+ release_srw_lock_exclusive = (PReleaseSRWLockExclusive)GetProcAddress(
library, "ReleaseSRWLockExclusive");
acquire_srw_lock_shared =
- (AcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
+ (PAcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
release_srw_lock_shared =
- (ReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
+ (PReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
if (initialize_srw_lock && acquire_srw_lock_exclusive &&
release_srw_lock_exclusive && acquire_srw_lock_shared &&
@@ -89,6 +88,18 @@
RTC_LOG(LS_VERBOSE) << "Loaded Native RW Lock";
native_rw_locks_supported = true;
}
+#else
+ // On WinUWP the symbols loaded from this library are directly present
+ // in the headers and thus loading the library is not required (and
+ // manually loading libraries is restricted due to WinUWP sandboxing).
+ initialize_srw_lock = InitializeSRWLock;
+ acquire_srw_lock_exclusive = AcquireSRWLockExclusive;
+ release_srw_lock_exclusive = ReleaseSRWLockExclusive;
+ acquire_srw_lock_shared = AcquireSRWLockShared;
+ release_srw_lock_shared = ReleaseSRWLockShared;
+
+ native_rw_locks_supported = true;
+#endif // !defined(WINUWP)
return native_rw_locks_supported;
}
diff --git a/rtc_base/timeutils.cc b/rtc_base/timeutils.cc
index dc5b611..0f79a87 100644
--- a/rtc_base/timeutils.cc
+++ b/rtc_base/timeutils.cc
@@ -45,6 +45,104 @@
return g_clock;
}
+#if defined(WINUWP)
+
+namespace {
+
+class TimeHelper final {
+ public:
+ TimeHelper(const TimeHelper&) = delete;
+
+ // Resets the clock based upon an NTP server. This routine must be called
+ // prior to the main system start-up to ensure all clocks are based upon
+ // an NTP server time if NTP synchronization is required. No critical
+ // section is used thus this method must be called prior to any clock
+ // routines being used.
+ static void SyncWithNtp(int64_t ntp_server_time_ms) {
+ auto& singleton = Singleton();
+ TIME_ZONE_INFORMATION time_zone;
+ GetTimeZoneInformation(&time_zone);
+ int64_t time_zone_bias_ns =
+ rtc::dchecked_cast<int64_t>(time_zone.Bias) * 60 * 1000 * 1000 * 1000;
+ singleton.app_start_time_ns_ =
+ (ntp_server_time_ms - kNTPTimeToUnixTimeEpochOffset) * 1000000 -
+ time_zone_bias_ns;
+ singleton.UpdateReferenceTime();
+ }
+
+ // Returns the number of nanoseconds that have passed since unix epoch.
+ static int64_t TicksNs() {
+ auto& singleton = Singleton();
+ int64_t result = 0;
+ LARGE_INTEGER qpcnt;
+ QueryPerformanceCounter(&qpcnt);
+ result = rtc::dchecked_cast<int64_t>(
+ (rtc::dchecked_cast<uint64_t>(qpcnt.QuadPart) * 100000 /
+ rtc::dchecked_cast<uint64_t>(singleton.os_ticks_per_second_)) *
+ 10000);
+ result = singleton.app_start_time_ns_ + result -
+ singleton.time_since_os_start_ns_;
+ return result;
+ }
+
+ private:
+ TimeHelper() {
+ TIME_ZONE_INFORMATION time_zone;
+ GetTimeZoneInformation(&time_zone);
+ int64_t time_zone_bias_ns =
+ rtc::dchecked_cast<int64_t>(time_zone.Bias) * 60 * 1000 * 1000 * 1000;
+ FILETIME ft;
+ // This will give us system file in UTC format.
+ GetSystemTimeAsFileTime(&ft);
+ LARGE_INTEGER li;
+ li.HighPart = ft.dwHighDateTime;
+ li.LowPart = ft.dwLowDateTime;
+
+ app_start_time_ns_ = (li.QuadPart - kFileTimeToUnixTimeEpochOffset) * 100 -
+ time_zone_bias_ns;
+
+ UpdateReferenceTime();
+ }
+
+ static TimeHelper& Singleton() {
+ static TimeHelper singleton;
+ return singleton;
+ }
+
+ void UpdateReferenceTime() {
+ LARGE_INTEGER qpfreq;
+ QueryPerformanceFrequency(&qpfreq);
+ os_ticks_per_second_ = rtc::dchecked_cast<int64_t>(qpfreq.QuadPart);
+
+ LARGE_INTEGER qpcnt;
+ QueryPerformanceCounter(&qpcnt);
+ time_since_os_start_ns_ = rtc::dchecked_cast<int64_t>(
+ (rtc::dchecked_cast<uint64_t>(qpcnt.QuadPart) * 100000 /
+ rtc::dchecked_cast<uint64_t>(os_ticks_per_second_)) *
+ 10000);
+ }
+
+ private:
+ static constexpr uint64_t kFileTimeToUnixTimeEpochOffset =
+ 116444736000000000ULL;
+ static constexpr uint64_t kNTPTimeToUnixTimeEpochOffset = 2208988800000L;
+
+ // The number of nanoseconds since unix system epoch
+ int64_t app_start_time_ns_;
+ // The number of nanoseconds since the OS started
+ int64_t time_since_os_start_ns_;
+ // The OS calculated ticks per second
+ int64_t os_ticks_per_second_;
+};
+
+} // namespace
+
+void SyncWithNtp(int64_t time_from_ntp_server_ms) {
+ TimeHelper::SyncWithNtp(time_from_ntp_server_ms);
+}
+
+#endif // defined(WINUWP)
+
int64_t SystemTimeNanos() {
int64_t ticks;
#if defined(WEBRTC_MAC)
@@ -71,6 +169,8 @@
clock_gettime(CLOCK_MONOTONIC, &ts);
ticks = kNumNanosecsPerSec * static_cast<int64_t>(ts.tv_sec) +
static_cast<int64_t>(ts.tv_nsec);
+#elif defined(WINUWP)
+ ticks = TimeHelper::TicksNs();
#elif defined(WEBRTC_WIN)
static volatile LONG last_timegettime = 0;
static volatile int64_t num_wrap_timegettime = 0;
diff --git a/rtc_base/timeutils.h b/rtc_base/timeutils.h
index 4e38a03..c6ddd73 100644
--- a/rtc_base/timeutils.h
+++ b/rtc_base/timeutils.h
@@ -58,6 +58,12 @@
// Returns previously set clock, or nullptr if no custom clock is being used.
ClockInterface* GetClockForTesting();
+#if defined(WINUWP)
+// Synchronizes the current clock based upon an NTP server's epoch in
+// milliseconds.
+void SyncWithNtp(int64_t time_from_ntp_server_ms);
+#endif // defined(WINUWP)
+
// Returns the actual system time, even if a clock is set for testing.
// Useful for timeouts while using a test clock, or for logging.
int64_t SystemTimeNanos();
diff --git a/rtc_base/win/windows_version.cc b/rtc_base/win/windows_version.cc
index f10e42c..65ef4fd 100644
--- a/rtc_base/win/windows_version.cc
+++ b/rtc_base/win/windows_version.cc
@@ -28,6 +28,8 @@
#error Creators Update SDK (10.0.15063.468) required.
#endif
+#if !defined(WINUWP)
+
namespace {
typedef BOOL(WINAPI* GetProductInfoPtr)(DWORD, DWORD, DWORD, DWORD, PDWORD);
@@ -171,6 +173,8 @@
} // namespace
+#endif // !defined(WINUWP)
+
namespace rtc {
namespace rtc_win {
namespace {
@@ -221,6 +225,10 @@
// this undocumented value appears to be similar to a patch number.
// Returns 0 if the value does not exist or it could not be read.
int GetUBR() {
+#if defined(WINUWP)
+ // The registry is not accessible for WinUWP sandboxed store applications.
+ return 0;
+#else
// The values under the CurrentVersion registry hive are mirrored under
// the corresponding Wow6432 hive.
static constexpr wchar_t kRegKeyWindowsNTCurrentVersion[] =
@@ -236,6 +244,7 @@
key.ReadValueDW(L"UBR", &ubr);
return static_cast<int>(ubr);
+#endif // defined(WINUWP)
}
} // namespace
@@ -294,6 +303,7 @@
processors_ = system_info.dwNumberOfProcessors;
allocation_granularity_ = system_info.dwAllocationGranularity;
+#if !defined(WINUWP)
GetProductInfoPtr get_product_info;
DWORD os_type;
@@ -366,11 +376,21 @@
// Windows is pre XP so we don't care but pick a safe default.
version_type_ = SUITE_HOME;
}
+#else
+ // WinUWP sandboxed store apps do not have a mechanism to determine
+ // product suite thus the most restricted suite is chosen.
+ version_type_ = SUITE_HOME;
+#endif // !defined(WINUWP)
}
OSInfo::~OSInfo() {}
std::string OSInfo::processor_model_name() {
+#if defined(WINUWP)
+ // WinUWP sandboxed store apps do not have the ability to
+ // probe the name of the current processor.
+ return "Unknown Processor (UWP)";
+#else
if (processor_model_name_.empty()) {
const wchar_t kProcessorNameString[] =
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
@@ -380,18 +400,24 @@
processor_model_name_ = rtc::ToUtf8(value);
}
return processor_model_name_;
+#endif // defined(WINUWP)
}
// static
OSInfo::WOW64Status OSInfo::GetWOW64StatusForProcess(HANDLE process_handle) {
+ BOOL is_wow64;
+#if defined(WINUWP)
+ if (!IsWow64Process(process_handle, &is_wow64))
+ return WOW64_UNKNOWN;
+#else
typedef BOOL(WINAPI * IsWow64ProcessFunc)(HANDLE, PBOOL);
IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
if (!is_wow64_process)
return WOW64_DISABLED;
- BOOL is_wow64 = FALSE;
if (!(*is_wow64_process)(process_handle, &is_wow64))
return WOW64_UNKNOWN;
+#endif // defined(WINUWP)
return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
}
diff --git a/rtc_base/win32.cc b/rtc_base/win32.cc
index e3482e3..480d97b 100644
--- a/rtc_base/win32.cc
+++ b/rtc_base/win32.cc
@@ -331,6 +331,11 @@
}
// Replace forward slashes with backslashes
std::replace(wfilename, wfilename + wlen, L'/', L'\\');
+#if defined(WINUWP)
+ // WinUWP sandboxed store applications require the paths to remain as
+ // relative paths.
+ filename->assign(wfilename);
+#else
// Convert to complete filename
DWORD full_len = ::GetFullPathName(wfilename, 0, nullptr, nullptr);
if (0 == full_len) {
@@ -360,9 +365,18 @@
// Already in long-path form.
}
filename->assign(start);
+#endif // defined(WINUWP)
+
return true;
}
+// Windows UWP applications cannot obtain versioning information from
+// the sandbox with intention (as behehaviour based on OS versioning rather
+// than feature discovery / compilation flags is discoraged and Windows
+// 10 is living continously updated version unlike previous versions
+// of Windows).
+#if !defined(WINUWP)
+
bool GetOsVersion(int* major, int* minor, int* build) {
OSVERSIONINFO info = {0};
info.dwOSVersionInfoSize = sizeof(info);
@@ -399,4 +413,6 @@
return ret;
}
+#endif // !defined(WINUWP)
+
} // namespace rtc
diff --git a/rtc_base/win32.h b/rtc_base/win32.h
index a5fd541..004c6b4 100644
--- a/rtc_base/win32.h
+++ b/rtc_base/win32.h
@@ -54,6 +54,8 @@
kWindowsVista = 6,
kWindows10 = 10,
};
+
+#if !defined(WINUWP)
bool GetOsVersion(int* major, int* minor, int* build);
inline bool IsWindowsVistaOrLater() {
@@ -87,6 +89,34 @@
level < SECURITY_MANDATORY_MEDIUM_RID);
}
+#else
+
+// When targetting WinUWP the OS must be Windows 10 (or greater) as lesser
+// Windows OS targets are not supported.
+inline bool IsWindowsVistaOrLater() {
+ return true;
+}
+
+inline bool IsWindowsXpOrLater() {
+ return true;
+}
+
+inline bool IsWindows8OrLater() {
+ return true;
+}
+
+inline bool IsWindows10OrLater() {
+ return true;
+}
+
+inline bool IsCurrentProcessLowIntegrity() {
+ // For WinUWP sandboxed store assume this is NOT a low integrity level run
+ // as application privileges can be requested in manifest as appropriate.
+ return true;
+}
+
+#endif // !defined(WINUWP)
+
} // namespace rtc
#endif // RTC_BASE_WIN32_H_
diff --git a/system_wrappers/source/clock.cc b/system_wrappers/source/clock.cc
index 4f5d9cf..32cf1de 100644
--- a/system_wrappers/source/clock.cc
+++ b/system_wrappers/source/clock.cc
@@ -80,7 +80,29 @@
}
};
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+class WinUwpRealTimeClock final : public RealTimeClock {
+ public:
+ WinUwpRealTimeClock() = default;
+ ~WinUwpRealTimeClock() override {}
+
+ protected:
+ timeval CurrentTimeVal() const override {
+ // The rtc::SystemTimeNanos() method is already time offset from a base
+ // epoch value and might as be synchronized against an NTP time server as
+ // an added bonus.
+ auto nanos = rtc::SystemTimeNanos();
+
+ struct timeval tv;
+
+ tv.tv_sec = rtc::dchecked_cast<long>(nanos / 1000000000);
+ tv.tv_usec = rtc::dchecked_cast<long>(nanos / 1000);
+
+ return tv;
+ }
+};
+
+#elif defined(WEBRTC_WIN)
// TODO(pbos): Consider modifying the implementation to synchronize itself
// against system time (update ref_point_, make it non-const) periodically to
// prevent clock drift.
@@ -202,7 +224,9 @@
#endif // defined(WEBRTC_POSIX)
Clock* Clock::GetRealTimeClock() {
-#if defined(WEBRTC_WIN)
+#if defined(WINUWP)
+ static Clock* const clock = new WinUwpRealTimeClock();
+#elif defined(WEBRTC_WIN)
static Clock* const clock = new WindowsRealTimeClock();
#elif defined(WEBRTC_POSIX)
static Clock* const clock = new UnixRealTimeClock();
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 7cd7b3e..f2d7937 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -6,8 +6,8 @@
# in the file PATENTS. All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
-import("../webrtc.gni")
import("//build/config/ui.gni")
+import("../webrtc.gni")
if (is_android) {
import("//build/config/android/rules.gni")
}
@@ -647,9 +647,15 @@
"statistics.h",
"video_decoder_proxy_factory.h",
"video_encoder_proxy_factory.h",
- "win/run_loop_win.cc",
]
- if (!is_win) {
+ if (current_os != "winuwp") {
+ # The filtering of *_win.cc is not done for WinUWP (intentionally) as
+ # most _win.cc files are compatible with WinUWP. However, the
+ # peek/dispatch Win32 runloops are entirely WinUWP incompatible thus
+ # WinUWP uses the generic runloop as defined for non-Windows targets.
+ sources += [ "win/run_loop_win.cc" ]
+ }
+ if (!is_win || current_os == "winuwp") {
sources += [
"run_loop.cc",
"run_loop.h",
diff --git a/webrtc.gni b/webrtc.gni
index 5c5214e..16f3b29 100644
--- a/webrtc.gni
+++ b/webrtc.gni
@@ -233,8 +233,8 @@
rtc_opus_dir = "//third_party/opus"
# Desktop capturer is supported only on Windows, OSX and Linux.
-rtc_desktop_capture_supported =
- is_win || is_mac || (is_linux && (rtc_use_x11 || rtc_use_pipewire))
+rtc_desktop_capture_supported = (is_win && current_os != "winuwp") || is_mac ||
+ (is_linux && (rtc_use_x11 || rtc_use_pipewire))
###############################################################################
# Templates