full_screen_window_detector.cc (4247B)
1 /* 2 * Copyright (c) 2019 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 #include "modules/desktop_capture/full_screen_window_detector.h" 12 13 #include <cstdint> 14 15 #include "api/function_view.h" 16 #include "modules/desktop_capture/desktop_capturer.h" 17 #include "modules/desktop_capture/full_screen_application_handler.h" 18 #include "rtc_base/time_utils.h" 19 20 #if defined(WEBRTC_WIN) 21 #include "modules/desktop_capture/win/full_screen_win_application_handler.h" 22 #endif 23 24 namespace webrtc { 25 26 FullScreenWindowDetector::FullScreenWindowDetector( 27 ApplicationHandlerFactory application_handler_factory) 28 : application_handler_factory_(application_handler_factory), 29 last_update_time_ms_(0), 30 previous_source_id_(0), 31 no_handler_source_id_(0) {} 32 33 DesktopCapturer::SourceId FullScreenWindowDetector::FindFullScreenWindow( 34 DesktopCapturer::SourceId original_source_id) { 35 if (app_handler_ == nullptr || 36 app_handler_->GetSourceId() != original_source_id) { 37 return 0; 38 } 39 return app_handler_->FindFullScreenWindow(window_list_, last_update_time_ms_); 40 } 41 42 void FullScreenWindowDetector::UpdateWindowListIfNeeded( 43 DesktopCapturer::SourceId original_source_id, 44 FunctionView<bool(DesktopCapturer::SourceList*)> get_sources) { 45 // Don't skip update if app_handler_ exists. 46 const bool skip_update = 47 !app_handler_ && (previous_source_id_ != original_source_id); 48 previous_source_id_ = original_source_id; 49 50 // Here is an attempt to avoid redundant creating application handler in case 51 // when an instance of WindowCapturer is used to generate a thumbnail to show 52 // in picker by calling SelectSource and CaptureFrame for every available 53 // source. 54 if (skip_update) { 55 return; 56 } 57 58 CreateApplicationHandlerIfNeeded(original_source_id); 59 if (app_handler_ == nullptr) { 60 // There is no FullScreenApplicationHandler specific for 61 // current application 62 return; 63 } 64 65 constexpr int64_t kUpdateIntervalMs = 500; 66 67 if ((TimeMillis() - last_update_time_ms_) <= kUpdateIntervalMs) { 68 return; 69 } 70 71 DesktopCapturer::SourceList window_list; 72 if (get_sources(&window_list)) { 73 last_update_time_ms_ = TimeMillis(); 74 75 bool should_swap_windows = true; 76 #if defined(WEBRTC_WIN) 77 bool is_original_source_window_alive = 78 ::IsWindow(reinterpret_cast<HWND>(original_source_id)); 79 bool is_original_source_enumerated = false; 80 for (auto& source : window_list) { 81 if (source.id == original_source_id) { 82 is_original_source_enumerated = true; 83 break; 84 } 85 } 86 // Don't swap window list if there is a mismatch between original window's 87 // state and its enumerated state. 88 should_swap_windows = 89 (is_original_source_enumerated == is_original_source_window_alive); 90 #endif 91 if (should_swap_windows) { 92 window_list_.swap(window_list); 93 } 94 } 95 } 96 97 void FullScreenWindowDetector::CreateApplicationHandlerIfNeeded( 98 DesktopCapturer::SourceId source_id) { 99 if (no_handler_source_id_ == source_id) { 100 return; 101 } 102 103 if (app_handler_ == nullptr || app_handler_->GetSourceId() != source_id) { 104 app_handler_ = application_handler_factory_ 105 ? application_handler_factory_(source_id) 106 : nullptr; 107 } 108 109 if (app_handler_ == nullptr) { 110 no_handler_source_id_ = source_id; 111 } else { 112 app_handler_->SetUseHeuristicFullscreenPowerPointWindows( 113 use_heuristic_fullscreen_powerpoint_windows_); 114 } 115 } 116 117 void FullScreenWindowDetector::CreateFullScreenApplicationHandlerForTest( 118 DesktopCapturer::SourceId source_id, 119 bool fullscreen_slide_show_started_after_capture_start) { 120 if (app_handler_) { 121 return; 122 } 123 #if defined(WEBRTC_WIN) 124 app_handler_ = std::make_unique<FullScreenPowerPointHandler>(source_id); 125 app_handler_->SetSlideShowCreationStateForTest( 126 fullscreen_slide_show_started_after_capture_start); 127 #endif 128 } 129 130 } // namespace webrtc