[Mac Window Occlusion] Reenable manual occlusion detection tests
This cl reenables manual occlusion detection for < macOS 13.0 and >= macOS 13.3. It also combines the previous two experiments (occlusion detection and display sleep) into a single experiment that combines both features, per a previous review with Catan. Test: out/Default/content_browsertests \ --gtest_filter=*WindowOcclusionBrowser* Bug: 883031 Change-Id: I2c5a4de21bb64406fa53bff7a7644df6671b7188 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4529204 Reviewed-by: Leonard Grey <lgrey@chromium.org> Commit-Queue: Jayson Adams <shrike@chromium.org> Cr-Commit-Position: refs/heads/main@{#1152207}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
10e1fa2d12
commit
93b0bbc89b
content/app_shim_remote_cocoa
@ -31,6 +31,14 @@ extern CONTENT_EXPORT const base::FeatureParam<bool>
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
// Returns YES if the specified version is less than 13.0 or more than 13.2.
|
||||
// Manual occlusion detection is not supported on macOS 13.0-13.2.
|
||||
+ (BOOL)manualOcclusionDetectionSupportedForVersion:(int32_t)major
|
||||
:(int32_t)minor;
|
||||
|
||||
// Returns YES if manual occlusion detection is supported for the current macOS.
|
||||
+ (BOOL)manualOcclusionDetectionSupportedForCurrentMacOSVersion;
|
||||
|
||||
// API exposed for testing.
|
||||
|
||||
// Resets the state of `sharedInstance` during tests.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#import "base/mac/scoped_objc_class_swizzler.h"
|
||||
#include "base/metrics/field_trial_params.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/system/sys_info.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
@ -24,8 +25,6 @@ using features::kMacWebContentsOcclusion;
|
||||
// Experiment features.
|
||||
const base::FeatureParam<bool> kEnhancedWindowOcclusionDetection{
|
||||
&kMacWebContentsOcclusion, "EnhancedWindowOcclusionDetection", false};
|
||||
const base::FeatureParam<bool> kDisplaySleepAndAppHideDetection{
|
||||
&kMacWebContentsOcclusion, "DisplaySleepAndAppHideDetection", false};
|
||||
|
||||
namespace {
|
||||
|
||||
@ -82,6 +81,25 @@ bool IsBrowserProcess() {
|
||||
return sharedInstance->get();
|
||||
}
|
||||
|
||||
+ (BOOL)manualOcclusionDetectionSupportedForVersion:(int32_t)major
|
||||
:(int32_t)minor {
|
||||
if (major != 13) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return minor >= 3;
|
||||
}
|
||||
|
||||
+ (BOOL)manualOcclusionDetectionSupportedForCurrentMacOSVersion {
|
||||
int32_t major_version;
|
||||
int32_t minor_version;
|
||||
int32_t bugfix_version;
|
||||
base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
|
||||
&bugfix_version);
|
||||
return [self manualOcclusionDetectionSupportedForVersion:
|
||||
major_version:minor_version];
|
||||
}
|
||||
|
||||
+ (void)resetSharedInstanceForTesting {
|
||||
[self sharedOcclusionChecker]->reset();
|
||||
}
|
||||
@ -125,6 +143,12 @@ bool IsBrowserProcess() {
|
||||
return _windowClassSwizzler.get();
|
||||
}
|
||||
|
||||
- (BOOL)isManualOcclusionDetectionEnabled {
|
||||
return [WebContentsOcclusionCheckerMac
|
||||
manualOcclusionDetectionSupportedForCurrentMacOSVersion] &&
|
||||
kEnhancedWindowOcclusionDetection.Get();
|
||||
}
|
||||
|
||||
// Alternative implementation of orderWindow:relativeTo:. Replaces
|
||||
// NSWindow's version, allowing the occlusion checker to learn about
|
||||
// window ordering events.
|
||||
@ -135,8 +159,10 @@ bool IsBrowserProcess() {
|
||||
->InvokeOriginal<void, NSWindowOrderingMode, NSInteger>(
|
||||
self, _cmd, orderingMode, otherWindowNumber);
|
||||
|
||||
if (!kEnhancedWindowOcclusionDetection.Get())
|
||||
if (![[WebContentsOcclusionCheckerMac sharedInstance]
|
||||
isManualOcclusionDetectionEnabled]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName:kWindowDidChangePositionInWindowList
|
||||
@ -148,7 +174,7 @@ bool IsBrowserProcess() {
|
||||
NSNotificationCenter* notificationCenter =
|
||||
[NSNotificationCenter defaultCenter];
|
||||
|
||||
if (kEnhancedWindowOcclusionDetection.Get()) {
|
||||
if ([self isManualOcclusionDetectionEnabled]) {
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(windowWillMove:)
|
||||
name:NSWindowWillMoveNotification
|
||||
@ -174,6 +200,17 @@ bool IsBrowserProcess() {
|
||||
selector:@selector(windowDidChangePositionInWindowList:)
|
||||
name:kWindowDidChangePositionInWindowList
|
||||
object:nil];
|
||||
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(displaysDidSleep:)
|
||||
name:NSWorkspaceScreensDidSleepNotification
|
||||
object:nil];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(displaysDidWake:)
|
||||
name:NSWorkspaceScreensDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
[notificationCenter addObserver:self
|
||||
@ -197,19 +234,6 @@ bool IsBrowserProcess() {
|
||||
selector:@selector(fullscreenTransitionComplete:)
|
||||
name:NSWindowDidExitFullScreenNotification
|
||||
object:nil];
|
||||
|
||||
if (kDisplaySleepAndAppHideDetection.Get()) {
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(displaysDidSleep:)
|
||||
name:NSWorkspaceScreensDidSleepNotification
|
||||
object:nil];
|
||||
[[[NSWorkspace sharedWorkspace] notificationCenter]
|
||||
addObserver:self
|
||||
selector:@selector(displaysDidWake:)
|
||||
name:NSWorkspaceScreensDidWakeNotification
|
||||
object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)windowCanTriggerOcclusionUpdates:(NSWindow*)window {
|
||||
@ -400,9 +424,8 @@ bool IsBrowserProcess() {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// If manual occlusion detection is disabled in the experiement, return the
|
||||
// answer from macOS.
|
||||
if (!kEnhancedWindowOcclusionDetection.Get()) {
|
||||
// If manual occlusion detection is disabled, return the answer from macOS.
|
||||
if (![self isManualOcclusionDetectionEnabled]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,13 @@ namespace {
|
||||
const int kNeverCalled = -100;
|
||||
|
||||
struct FeatureState {
|
||||
bool feature_enabled = false;
|
||||
bool enhanced_occlusion_detection_enabled = false;
|
||||
bool display_sleep_detection_enabled = false;
|
||||
};
|
||||
|
||||
struct Version {
|
||||
int32_t major;
|
||||
int32_t minor;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@ -141,6 +145,8 @@ struct FeatureState {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
|
||||
// The tests should access WebContentsOcclusionCheckerMac directly, rather
|
||||
// than through NSClassFromString(). See crbug.com/1450724 .
|
||||
[WebContentVisibilityUpdateWatcher performOcclusionStateUpdatesSwizzler]
|
||||
.reset(new base::mac::ScopedObjCClassSwizzler(
|
||||
NSClassFromString(@"WebContentsOcclusionCheckerMac"),
|
||||
@ -329,12 +335,9 @@ class WindowOcclusionBrowserTestMac
|
||||
public ContentBrowserTest {
|
||||
public:
|
||||
WindowOcclusionBrowserTestMac() {
|
||||
if (GetParam().feature_enabled) {
|
||||
if (GetParam().enhanced_occlusion_detection_enabled) {
|
||||
base::FieldTrialParams params;
|
||||
if (GetParam().enhanced_occlusion_detection_enabled)
|
||||
params["EnhancedWindowOcclusionDetection"] = "true";
|
||||
if (GetParam().display_sleep_detection_enabled)
|
||||
params["DisplaySleepAndAppHideDetection"] = "true";
|
||||
params["EnhancedWindowOcclusionDetection"] = "true";
|
||||
_features.InitAndEnableFeatureWithParameters(
|
||||
features::kMacWebContentsOcclusion, params);
|
||||
} else {
|
||||
@ -343,9 +346,10 @@ class WindowOcclusionBrowserTestMac
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
if (base::mac::IsAtLeastOS13()) {
|
||||
if (![NSClassFromString(@"WebContentsOcclusionCheckerMac")
|
||||
manualOcclusionDetectionSupportedForCurrentMacOSVersion]) {
|
||||
GTEST_SKIP()
|
||||
<< "Manual window occlusion detection is broken on macOS Ventura.";
|
||||
<< "Manual window occlusion detection is broken on macOS 13.0-13.2.";
|
||||
}
|
||||
ContentBrowserTest::SetUp();
|
||||
}
|
||||
@ -467,8 +471,7 @@ class WindowOcclusionBrowserTestMac
|
||||
void OrderWindowFront(NSWindow* window) {
|
||||
base::scoped_nsobject<WebContentVisibilityUpdateCounter> watcher;
|
||||
|
||||
if (!kEnhancedWindowOcclusionDetection.Get() &&
|
||||
!kDisplaySleepAndAppHideDetection.Get()) {
|
||||
if (!kEnhancedWindowOcclusionDetection.Get()) {
|
||||
watcher.reset([[WebContentVisibilityUpdateCounter alloc] init]);
|
||||
}
|
||||
|
||||
@ -477,8 +480,6 @@ class WindowOcclusionBrowserTestMac
|
||||
|
||||
if (kEnhancedWindowOcclusionDetection.Get()) {
|
||||
WaitForOcclusionUpdate();
|
||||
} else if (!kDisplaySleepAndAppHideDetection.Get()) {
|
||||
EXPECT_TRUE([WebContentVisibilityUpdateCounter methodNeverCalled]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,55 +570,45 @@ using WindowOcclusionBrowserTestMacWithoutOcclusionFeature =
|
||||
WindowOcclusionBrowserTestMac;
|
||||
using WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature =
|
||||
WindowOcclusionBrowserTestMac;
|
||||
using WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature =
|
||||
WindowOcclusionBrowserTestMac;
|
||||
|
||||
// Tests that should only work without the occlusion detection feature.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
NoFeature,
|
||||
WindowOcclusionBrowserTestMacWithoutOcclusionFeature,
|
||||
::testing::Values(FeatureState{.feature_enabled = false},
|
||||
// Feature should be a no-op without parameters.
|
||||
FeatureState{.feature_enabled = true}));
|
||||
INSTANTIATE_TEST_SUITE_P(NoFeature,
|
||||
WindowOcclusionBrowserTestMacWithoutOcclusionFeature,
|
||||
::testing::Values(FeatureState{
|
||||
.enhanced_occlusion_detection_enabled = false}));
|
||||
|
||||
// Tests that should work with or without the occlusion detection feature.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
Common,
|
||||
WindowOcclusionBrowserTestMac,
|
||||
::testing::Values(FeatureState{.feature_enabled = false},
|
||||
FeatureState{.feature_enabled = true},
|
||||
FeatureState{
|
||||
.feature_enabled = true,
|
||||
.enhanced_occlusion_detection_enabled = true},
|
||||
FeatureState{.feature_enabled = true,
|
||||
.display_sleep_detection_enabled = true},
|
||||
FeatureState{.feature_enabled = true,
|
||||
.enhanced_occlusion_detection_enabled = true,
|
||||
.display_sleep_detection_enabled = true}));
|
||||
::testing::Values(
|
||||
FeatureState{.enhanced_occlusion_detection_enabled = false},
|
||||
FeatureState{.enhanced_occlusion_detection_enabled = true}));
|
||||
|
||||
// Tests that require enhanced window occlusion detection.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
EnhancedWindowOcclusionDetection,
|
||||
WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature,
|
||||
::testing::Values(
|
||||
FeatureState{.feature_enabled = true,
|
||||
.enhanced_occlusion_detection_enabled = true},
|
||||
FeatureState{.feature_enabled = true,
|
||||
.enhanced_occlusion_detection_enabled = true,
|
||||
.display_sleep_detection_enabled = true}));
|
||||
::testing::Values(FeatureState{
|
||||
.enhanced_occlusion_detection_enabled = true}));
|
||||
|
||||
// Tests that require display sleep and app hide detection.
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
DisplaySleepAndAppHideDetection,
|
||||
WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature,
|
||||
::testing::Values(FeatureState{.feature_enabled = true,
|
||||
.display_sleep_detection_enabled = true},
|
||||
FeatureState{.feature_enabled = true,
|
||||
.enhanced_occlusion_detection_enabled = true,
|
||||
.display_sleep_detection_enabled = true}));
|
||||
// Tests that we correctly disallow unsupported macOS versions.
|
||||
IN_PROC_BROWSER_TEST_P(WindowOcclusionBrowserTestMac, MacOSVersionChecking) {
|
||||
Class WebContentsOcclusionCheckerMac =
|
||||
NSClassFromString(@"WebContentsOcclusionCheckerMac");
|
||||
std::vector<Version> versions = {
|
||||
{11, 0, true}, {12, 0, true}, {12, 9, true}, {13, 0, false},
|
||||
{13, 1, false}, {13, 2, false}, {13, 3, true}, {14, 0, true}};
|
||||
|
||||
// Test that enhanced occlusion detection doesn't work if the feature's not
|
||||
// enabled.
|
||||
for (const auto& version : versions) {
|
||||
bool supported = [WebContentsOcclusionCheckerMac manualOcclusionDetectionSupportedForVersion:version.major
|
||||
:version.minor];
|
||||
EXPECT_EQ(supported, version.supported);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that enhanced occlusion detection isn't triggered if the feature's
|
||||
// not enabled.
|
||||
IN_PROC_BROWSER_TEST_P(WindowOcclusionBrowserTestMacWithoutOcclusionFeature,
|
||||
ManualOcclusionDetectionDisabled) {
|
||||
InitWindowA();
|
||||
@ -820,7 +811,7 @@ IN_PROC_BROWSER_TEST_P(
|
||||
|
||||
// Checks that web contents are marked kHidden on display sleep.
|
||||
IN_PROC_BROWSER_TEST_P(
|
||||
WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature,
|
||||
WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature,
|
||||
OcclusionDetectionOnDisplaySleep) {
|
||||
InitWindowA();
|
||||
|
||||
|
Reference in New Issue
Block a user