| /* |
| * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "modules/desktop_capture/full_screen_window_detector.h" |
| |
| #include <cstdint> |
| |
| #include "api/function_view.h" |
| #include "modules/desktop_capture/desktop_capturer.h" |
| #include "modules/desktop_capture/full_screen_application_handler.h" |
| #include "rtc_base/time_utils.h" |
| |
| #if defined(WEBRTC_WIN) |
| #include "modules/desktop_capture/win/full_screen_win_application_handler.h" |
| #endif |
| |
| namespace webrtc { |
| |
| FullScreenWindowDetector::FullScreenWindowDetector( |
| ApplicationHandlerFactory application_handler_factory) |
| : application_handler_factory_(application_handler_factory), |
| last_update_time_ms_(0), |
| previous_source_id_(0), |
| no_handler_source_id_(0) {} |
| |
| DesktopCapturer::SourceId FullScreenWindowDetector::FindFullScreenWindow( |
| DesktopCapturer::SourceId original_source_id) { |
| if (app_handler_ == nullptr || |
| app_handler_->GetSourceId() != original_source_id) { |
| return 0; |
| } |
| return app_handler_->FindFullScreenWindow(window_list_, last_update_time_ms_); |
| } |
| |
| void FullScreenWindowDetector::UpdateWindowListIfNeeded( |
| DesktopCapturer::SourceId original_source_id, |
| FunctionView<bool(DesktopCapturer::SourceList*)> get_sources) { |
| // Don't skip update if app_handler_ exists. |
| const bool skip_update = |
| !app_handler_ && (previous_source_id_ != original_source_id); |
| previous_source_id_ = original_source_id; |
| |
| // Here is an attempt to avoid redundant creating application handler in case |
| // when an instance of WindowCapturer is used to generate a thumbnail to show |
| // in picker by calling SelectSource and CaptureFrame for every available |
| // source. |
| if (skip_update) { |
| return; |
| } |
| |
| CreateApplicationHandlerIfNeeded(original_source_id); |
| if (app_handler_ == nullptr) { |
| // There is no FullScreenApplicationHandler specific for |
| // current application |
| return; |
| } |
| |
| constexpr int64_t kUpdateIntervalMs = 500; |
| |
| if ((TimeMillis() - last_update_time_ms_) <= kUpdateIntervalMs) { |
| return; |
| } |
| |
| DesktopCapturer::SourceList window_list; |
| if (get_sources(&window_list)) { |
| last_update_time_ms_ = TimeMillis(); |
| |
| bool should_swap_windows = true; |
| #if defined(WEBRTC_WIN) |
| bool is_original_source_window_alive = |
| ::IsWindow(reinterpret_cast<HWND>(original_source_id)); |
| bool is_original_source_enumerated = false; |
| for (auto& source : window_list) { |
| if (source.id == original_source_id) { |
| is_original_source_enumerated = true; |
| break; |
| } |
| } |
| // Don't swap window list if there is a mismatch between original window's |
| // state and its enumerated state. |
| should_swap_windows = |
| (is_original_source_enumerated == is_original_source_window_alive); |
| #endif |
| if (should_swap_windows) { |
| window_list_.swap(window_list); |
| } |
| } |
| } |
| |
| void FullScreenWindowDetector::CreateApplicationHandlerIfNeeded( |
| DesktopCapturer::SourceId source_id) { |
| if (no_handler_source_id_ == source_id) { |
| return; |
| } |
| |
| if (app_handler_ == nullptr || app_handler_->GetSourceId() != source_id) { |
| app_handler_ = application_handler_factory_ |
| ? application_handler_factory_(source_id) |
| : nullptr; |
| } |
| |
| if (app_handler_ == nullptr) { |
| no_handler_source_id_ = source_id; |
| } else { |
| app_handler_->SetUseHeuristicFullscreenPowerPointWindows( |
| use_heuristic_fullscreen_powerpoint_windows_); |
| } |
| } |
| |
| void FullScreenWindowDetector::CreateFullScreenApplicationHandlerForTest( |
| DesktopCapturer::SourceId source_id, |
| bool fullscreen_slide_show_started_after_capture_start) { |
| if (app_handler_) { |
| return; |
| } |
| #if defined(WEBRTC_WIN) |
| app_handler_ = std::make_unique<FullScreenPowerPointHandler>(source_id); |
| app_handler_->SetSlideShowCreationStateForTest( |
| fullscreen_slide_show_started_after_capture_start); |
| #endif |
| } |
| |
| } // namespace webrtc |