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 #include "modules/desktop_capture/full_screen_application_handler.h"
13 #include "rtc_base/time_utils.h"
14 
15 namespace webrtc {
16 
FullScreenWindowDetector(ApplicationHandlerFactory application_handler_factory)17 FullScreenWindowDetector::FullScreenWindowDetector(
18     ApplicationHandlerFactory application_handler_factory)
19     : application_handler_factory_(application_handler_factory),
20       last_update_time_ms_(0),
21       previous_source_id_(0),
22       no_handler_source_id_(0) {}
23 
FindFullScreenWindow(DesktopCapturer::SourceId original_source_id)24 DesktopCapturer::SourceId FullScreenWindowDetector::FindFullScreenWindow(
25     DesktopCapturer::SourceId original_source_id) {
26   if (app_handler_ == nullptr ||
27       app_handler_->GetSourceId() != original_source_id) {
28     return 0;
29   }
30   return app_handler_->FindFullScreenWindow(window_list_, last_update_time_ms_);
31 }
32 
UpdateWindowListIfNeeded(DesktopCapturer::SourceId original_source_id,rtc::FunctionView<bool (DesktopCapturer::SourceList *)> get_sources)33 void FullScreenWindowDetector::UpdateWindowListIfNeeded(
34     DesktopCapturer::SourceId original_source_id,
35     rtc::FunctionView<bool(DesktopCapturer::SourceList*)> get_sources) {
36   const bool skip_update = previous_source_id_ != original_source_id;
37   previous_source_id_ = original_source_id;
38 
39   // Here is an attempt to avoid redundant creating application handler in case
40   // when an instance of WindowCapturer is used to generate a thumbnail to show
41   // in picker by calling SelectSource and CaptureFrame for every available
42   // source.
43   if (skip_update) {
44     return;
45   }
46 
47   CreateApplicationHandlerIfNeeded(original_source_id);
48   if (app_handler_ == nullptr) {
49     // There is no FullScreenApplicationHandler specific for
50     // current application
51     return;
52   }
53 
54   constexpr int64_t kUpdateIntervalMs = 500;
55 
56   if ((rtc::TimeMillis() - last_update_time_ms_) <= kUpdateIntervalMs) {
57     return;
58   }
59 
60   DesktopCapturer::SourceList window_list;
61   if (get_sources(&window_list)) {
62     last_update_time_ms_ = rtc::TimeMillis();
63     window_list_.swap(window_list);
64   }
65 }
66 
CreateApplicationHandlerIfNeeded(DesktopCapturer::SourceId source_id)67 void FullScreenWindowDetector::CreateApplicationHandlerIfNeeded(
68     DesktopCapturer::SourceId source_id) {
69   if (no_handler_source_id_ == source_id) {
70     return;
71   }
72 
73   if (app_handler_ == nullptr || app_handler_->GetSourceId() != source_id) {
74     app_handler_ = application_handler_factory_
75                        ? application_handler_factory_(source_id)
76                        : nullptr;
77   }
78 
79   if (app_handler_ == nullptr) {
80     no_handler_source_id_ = source_id;
81   }
82 }
83 
84 }  // namespace webrtc
85