-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
M116: Add fullscreen presentation detector to ScreenCaptureKit capturer
This CL adds a module that tracks fullscreen presentations when ScreenCaptureKit is used on macOS. The user selects the editor window of the slideshow. Once the slideshow starts, the module will automatically change what window is captured so that the fullscreen slideshow is captured. This feature is already implemented for the current macOS window capturer. This CL is needed in order to not break this functionality once we change to use ScreenCaptureKit on macOS. Internal design doc: go/macos-fullscreen-feature The CL is tested on macOS 13.4 with the following applications: - Microsoft PowerPoint for Mac 16.73 - Apache OpenOffice 4.1.14 - Keynote 13.1 (cherry picked from commit f6eb524) Bug: chromium:1348011 Change-Id: I0ec0311bcf758eb6987f6e30e1d6fee15bcd9302 Low-Coverage-Reason: The reported test coverage is wrong. The newly added module has a high test coverage. The existing code that interacts with the ScreenCaptureKit API is hard to test, I will look into adding tests as a follow up. Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4295824 Commit-Queue: Johannes Kron <kron@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Reviewed-by: Mark Foltz <mfoltz@chromium.org> Cr-Original-Commit-Position: refs/heads/main@{#1160326} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4644171 Cr-Commit-Position: refs/branch-heads/5845@{#101} Cr-Branched-From: 5a5dff6-refs/heads/main@{#1160321}
- Loading branch information
Johannes Kron
authored and
Chromium LUCI CQ
committed
Jun 26, 2023
1 parent
01735cb
commit 8fe371f
Showing
11 changed files
with
1,002 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
content/browser/media/capture/screen_capture_kit_fullscreen_module.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_SCREEN_CAPTURE_KIT_FULLSCREEN_MODULE_H_ | ||
#define CONTENT_BROWSER_MEDIA_CAPTURE_SCREEN_CAPTURE_KIT_FULLSCREEN_MODULE_H_ | ||
|
||
#include <CoreGraphics/CGWindow.h> | ||
#import <ScreenCaptureKit/ScreenCaptureKit.h> | ||
#include "base/mac/scoped_nsobject.h" | ||
#import "base/task/single_thread_task_runner.h" | ||
#include "base/timer/timer.h" | ||
#include "content/common/content_export.h" | ||
|
||
namespace content { | ||
|
||
class API_AVAILABLE(macos(12.3)) | ||
CONTENT_EXPORT ScreenCaptureKitResetStreamInterface { | ||
public: | ||
// This function is called if the ScreenCaptureKitFullScreenModule detects a | ||
// fullscreen presentation that corresponds to the originally captured window. | ||
// The parameter is the fullscreen window. It is also called with the original | ||
// window as parameter if the fullscreen window is no longer on screen. | ||
virtual void ResetStreamTo(SCWindow* window) = 0; | ||
}; | ||
|
||
class API_AVAILABLE(macos(12.3)) | ||
CONTENT_EXPORT ScreenCaptureKitFullscreenModule { | ||
public: | ||
// These values are persisted to logs. Entries should not be renumbered and | ||
// numeric values should never be reused. | ||
enum class Mode { | ||
kUnsupported = 0, | ||
kPowerPoint = 1, | ||
kOpenOffice = 2, | ||
kKeynote = 3, | ||
kLibreOffice = 4, | ||
kMaxValue = kLibreOffice, | ||
}; | ||
|
||
using ContentHandler = | ||
base::OnceCallback<void(base::scoped_nsobject<SCShareableContent>)>; | ||
using GetShareableContentCallback = | ||
base::RepeatingCallback<void(ContentHandler)>; | ||
|
||
ScreenCaptureKitFullscreenModule( | ||
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner, | ||
ScreenCaptureKitResetStreamInterface& reset_stream_interface, | ||
CGWindowID original_window_id, | ||
pid_t original_window_pid, | ||
Mode mode); | ||
~ScreenCaptureKitFullscreenModule(); | ||
|
||
void Start(); | ||
void Reset(); | ||
|
||
bool is_fullscreen_window_active() const { return fullscreen_mode_active_; } | ||
Mode get_mode() const { return mode_; } | ||
|
||
// Sets a callback to be used whenever the ScreenCaptureKit OS API | ||
// GetShareableContent is called. Used in tests to enable mocking of this API. | ||
void set_get_sharable_content_for_test( | ||
GetShareableContentCallback get_shareable_content) { | ||
get_shareable_content_for_test_ = get_shareable_content; | ||
} | ||
|
||
private: | ||
void CheckForFullscreenPresentation(); | ||
void OnFullscreenShareableContentCreated( | ||
base::scoped_nsobject<SCShareableContent> content); | ||
void OnExitFullscreenShareableContentCreated( | ||
base::scoped_nsobject<SCShareableContent> content); | ||
SCWindow* GetFullscreenWindow( | ||
base::scoped_nsobject<SCShareableContent> content, | ||
SCWindow* editor_window, | ||
int number_of_impress_editor_windows) const; | ||
|
||
const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_; | ||
|
||
// Interface to the owner of the SCK stream. | ||
ScreenCaptureKitResetStreamInterface& reset_stream_interface_; | ||
|
||
// Identifier of the original window that is captured. | ||
const CGWindowID original_window_id_; | ||
const pid_t original_window_pid_; | ||
|
||
// The mode, corresponding to what slideshow application we're tracking. | ||
const Mode mode_; | ||
// True, if we've detected a fullscreen presentation and requested the stream | ||
// to be reset to the new window. | ||
bool fullscreen_mode_active_ = false; | ||
// Identified of the fullscreen window. | ||
CGWindowID fullscreen_window_id_ = 0; | ||
// Callback to mock function that is used in tests to mock the SCK OS API | ||
// GetShareableContent. | ||
GetShareableContentCallback get_shareable_content_for_test_; | ||
|
||
base::RepeatingTimer timer_; | ||
|
||
base::WeakPtrFactory<ScreenCaptureKitFullscreenModule> weak_factory_{this}; | ||
}; | ||
|
||
// Creates and returns a ScreenCaptureKitFullscreenModule if `original_window` | ||
// corresponds to a supported slideshow application. `reset_stream_interface` is | ||
// a reference to the object that owns the SCK stream. Upon detection of a | ||
// fullscreen slideshow, the reset function will be called. | ||
// `reset_stream_interface` must outlive the returned fullscreen module. | ||
// `device_task_runner` specifies the task runner where all operations are run. | ||
std::unique_ptr<ScreenCaptureKitFullscreenModule> CONTENT_EXPORT | ||
MaybeCreateScreenCaptureKitFullscreenModule( | ||
scoped_refptr<base::SingleThreadTaskRunner> device_task_runner, | ||
ScreenCaptureKitResetStreamInterface& reset_stream_interface, | ||
SCWindow* original_window) API_AVAILABLE(macos(12.3)); | ||
|
||
} // namespace content | ||
|
||
#endif // CONTENT_BROWSER_MEDIA_CAPTURE_SCREEN_CAPTURE_KIT_FULLSCREEN_MODULE_H_ |
Oops, something went wrong.