source: webkit/trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h@ 284786

Last change on this file since 284786 was 284786, checked in by Wenson Hsieh, 4 years ago

REGRESSION (r284079): Audio continues playing on hulu.com in private browsing mode after closing the tab
https://bugs.webkit.org/show_bug.cgi?id=232113
rdar://84399283

Reviewed by Chris Dumez.

Source/WebKit:

I inadvertently introduced a ref-counting cycle between RemoteRenderingBackend and RemoteDisplayListRecorder
after IPC stream refactoring in r284079, since RemoteDisplayListRecorder directly strongly refs the rendering
backend, and the rendering backend indirectly holds on to RemoteDisplayListRecorders through remote image
buffers in the resource cache. Since RemoteRenderingBackend also strongly refs GPUConnectionToWebProcess as
well, this caused the entire GPUConnectionToWebProcess to leak after tearing down the connected web process, if
the web process ever installed a remote rendering backend for 2D canvas.

To avoid this cycle, turn RemoteDisplayListRecorder's m_renderingBackend into a RefPtr instead of a Ref, and
clear it out in stopListeningForIPC(). This also means that we no longer need a separate boolean flag to
ensure that RemoteDisplayListRecorder::stopListeningForIPC() is idempotent, so we also remove
m_isListeningForIPC altogether.

Test: GPUProcess.DoNotLeakConnectionAfterClosingWebPage

  • GPUProcess/GPUConnectionToWebProcess.cpp:

(WebKit::GPUConnectionToWebProcess::GPUConnectionToWebProcess):
(WebKit::GPUConnectionToWebProcess::~GPUConnectionToWebProcess):

  • GPUProcess/GPUConnectionToWebProcess.h:

(WebKit::GPUConnectionToWebProcess::objectCountForTesting):

  • GPUProcess/GPUProcess.cpp:

(WebKit::GPUProcess::webProcessConnectionCountForTesting):

Add support for a testing-only SPI hook to ask for the live GPUConnectionToWebProcess count. This retrieves a
statically incremented/decremented count of the GPUConnectionToWebProcess instances that exist in the GPU
process; importantly, this is different from asking the GPUProcess for the number of connections in
m_webProcessConnections, since the latter will be 0 even when one or more GPUConnectionToWebProcesses are
still alive.

  • GPUProcess/GPUProcess.h:
  • GPUProcess/GPUProcess.messages.in:
  • GPUProcess/graphics/RemoteDisplayListRecorder.cpp:

(WebKit::RemoteDisplayListRecorder::RemoteDisplayListRecorder):

Also fix a leak caused by RemoteDisplayListRecorder and RemoteImageBuffer strongly reffing each other. Since
RemoteImageBuffer owns RemoteDisplayListRecorder, the backpointer from RemoteDisplayListRecorder to the image
buffer should be weak, not strong.

(WebKit::RemoteDisplayListRecorder::startListeningForIPC):
(WebKit::RemoteDisplayListRecorder::stopListeningForIPC):
(WebKit::RemoteDisplayListRecorder::paintFrameForMedia):

  • GPUProcess/graphics/RemoteDisplayListRecorder.h:

(): Deleted.

  • GPUProcess/graphics/RemoteRenderingBackend.cpp:

(WebKit::RemoteRenderingBackend::stopListeningForIPC):

Adjust this logic to ensure that we finish pending work and destroy cached resources *right before* we stop
listening for all stream IPC messages. Since RemoteDisplayListRecorder now clears out its pointer to the
rendering backend in stopListeningForIPC(), we'll need to ensure that any pending IPC stream messages that
might cause RemoteDisplayListRecorder to call into the back end are processed before we sever the IPC stream
connection for good by removing all receivers.

  • UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:

Add the new testing SPI (see above for more details).

  • UIProcess/API/Cocoa/WKWebViewTesting.mm:

(-[WKWebView _gpuToWebProcessConnectionCountForTesting:]):

  • UIProcess/GPU/GPUProcessProxy.cpp:

(WebKit::GPUProcessProxy::webProcessConnectionCountForTesting):

  • UIProcess/GPU/GPUProcessProxy.h:

Tools:

Add a new API test to verify that the GPU to web prcoess connection isn't leaked in the GPU process. See WebKit
ChangeLog for more details.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
  • TestWebKitAPI/Tests/WebKitCocoa/canvas-image-data.html: Added.
  • TestWebKitAPI/cocoa/TestWKWebView.h:
  • TestWebKitAPI/cocoa/TestWKWebView.mm:

(-[WKWebView gpuToWebProcessConnectionCount]):

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/*
2 * Copyright (C) 2016-2020 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#import <WebKit/WebKit.h>
27#import <wtf/RetainPtr.h>
28
29@class _WKProcessPoolConfiguration;
30
31#if PLATFORM(IOS_FAMILY)
32@class _WKActivatedElementInfo;
33@class _WKTextInputContext;
34@protocol UITextInputInternal;
35@protocol UITextInputMultiDocument;
36@protocol UITextInputPrivate;
37@protocol UIWKInteractionViewProtocol;
38#endif
39
40@interface WKWebView (AdditionalDeclarations)
41#if PLATFORM(MAC)
42- (void)paste:(id)sender;
43- (void)changeAttributes:(id)sender;
44- (void)changeColor:(id)sender;
45- (void)superscript:(id)sender;
46- (void)subscript:(id)sender;
47- (void)unscript:(id)sender;
48#endif
49@end
50
51@interface WKWebView (TestWebKitAPI)
52#if PLATFORM(IOS_FAMILY)
53@property (nonatomic, readonly) UIView <UITextInputPrivate, UITextInputInternal, UITextInputMultiDocument, UIWKInteractionViewProtocol, UITextInputTokenizer> *textInputContentView;
54- (NSArray<_WKTextInputContext *> *)synchronouslyRequestTextInputContextsInRect:(CGRect)rect;
55#endif
56@property (nonatomic, readonly) NSUInteger gpuToWebProcessConnectionCount;
57@property (nonatomic, readonly) NSString *contentsAsString;
58@property (nonatomic, readonly) NSArray<NSString *> *tagsInBody;
59- (void)loadTestPageNamed:(NSString *)pageName;
60- (void)synchronouslyGoBack;
61- (void)synchronouslyGoForward;
62- (void)synchronouslyLoadHTMLString:(NSString *)html;
63- (void)synchronouslyLoadHTMLString:(NSString *)html baseURL:(NSURL *)url;
64- (void)synchronouslyLoadHTMLString:(NSString *)html preferences:(WKWebpagePreferences *)preferences;
65- (void)synchronouslyLoadRequest:(NSURLRequest *)request;
66- (void)synchronouslyLoadTestPageNamed:(NSString *)pageName;
67- (BOOL)_synchronouslyExecuteEditCommand:(NSString *)command argument:(NSString *)argument;
68- (void)expectElementTagsInOrder:(NSArray<NSString *> *)tagNames;
69- (void)expectElementCount:(NSInteger)count querySelector:(NSString *)querySelector;
70- (void)expectElementTag:(NSString *)tagName toComeBefore:(NSString *)otherTagName;
71- (BOOL)evaluateMediaQuery:(NSString *)query;
72- (NSString *)stringByEvaluatingJavaScript:(NSString *)script;
73- (id)objectByEvaluatingJavaScriptWithUserGesture:(NSString *)script;
74- (id)objectByEvaluatingJavaScript:(NSString *)script;
75- (id)objectByCallingAsyncFunction:(NSString *)script withArguments:(NSDictionary *)arguments error:(NSError **)errorOut;
76- (unsigned)waitUntilClientWidthIs:(unsigned)expectedClientWidth;
77@end
78
79@interface TestMessageHandler : NSObject <WKScriptMessageHandler>
80- (void)addMessage:(NSString *)message withHandler:(dispatch_block_t)handler;
81@end
82
83@interface TestWKWebView : WKWebView
84- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration processPoolConfiguration:(_WKProcessPoolConfiguration *)processPoolConfiguration;
85- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration addToWindow:(BOOL)addToWindow;
86- (void)synchronouslyLoadHTMLStringAndWaitUntilAllImmediateChildFramesPaint:(NSString *)html;
87- (void)clearMessageHandlers:(NSArray *)messageNames;
88- (void)performAfterReceivingMessage:(NSString *)message action:(dispatch_block_t)action;
89- (void)performAfterReceivingAnyMessage:(void (^)(NSString *))action;
90- (void)waitForMessage:(NSString *)message;
91
92// This function waits until a DOM load event is fired.
93// FIXME: Rename this function to better describe what "after loading" means.
94- (void)performAfterLoading:(dispatch_block_t)actions;
95
96- (void)waitForNextPresentationUpdate;
97- (void)waitUntilActivityStateUpdateDone;
98- (void)forceDarkMode;
99- (NSString *)stylePropertyAtSelectionStart:(NSString *)propertyName;
100- (NSString *)stylePropertyAtSelectionEnd:(NSString *)propertyName;
101- (void)collapseToStart;
102- (void)collapseToEnd;
103- (void)addToTestWindow;
104- (BOOL)selectionRangeHasStartOffset:(int)start endOffset:(int)end;
105- (void)clickOnElementID:(NSString *)elementID;
106- (void)waitForPendingMouseEvents;
107- (void)focus;
108@end
109
110#if PLATFORM(IOS_FAMILY)
111@interface UIView (WKTestingUIViewUtilities)
112- (UIView *)wkFirstSubviewWithClass:(Class)targetClass;
113- (UIView *)wkFirstSubviewWithBoundsSize:(CGSize)size;
114@end
115#endif
116
117#if PLATFORM(IOS_FAMILY)
118@interface WKContentView : UIView
119@end
120
121@interface TestWKWebView (IOSOnly)
122@property (nonatomic, readonly) RetainPtr<NSArray> selectionRectsAfterPresentationUpdate;
123@property (nonatomic, readonly) CGRect caretViewRectInContentCoordinates;
124@property (nonatomic, readonly) NSArray<NSValue *> *selectionViewRectsInContentCoordinates;
125- (_WKActivatedElementInfo *)activatedElementAtPosition:(CGPoint)position;
126- (void)evaluateJavaScriptAndWaitForInputSessionToChange:(NSString *)script;
127- (WKContentView *)wkContentView;
128@end
129#endif
130
131#if PLATFORM(MAC)
132@interface TestWKWebView (MacOnly)
133// Simulates clicking with a pressure-sensitive device, if possible.
134- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure;
135- (void)mouseDownAtPoint:(NSPoint)pointInWindow simulatePressure:(BOOL)simulatePressure withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType;
136- (void)mouseDragToPoint:(NSPoint)pointInWindow;
137- (void)mouseEnterAtPoint:(NSPoint)pointInWindow;
138- (void)mouseUpAtPoint:(NSPoint)pointInWindow;
139- (void)mouseUpAtPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags eventType:(NSEventType)eventType;
140- (void)mouseMoveToPoint:(NSPoint)pointInWindow withFlags:(NSEventModifierFlags)flags;
141- (void)sendClicksAtPoint:(NSPoint)pointInWindow numberOfClicks:(NSUInteger)numberOfClicks;
142- (void)sendClickAtPoint:(NSPoint)pointInWindow;
143- (void)wheelEventAtPoint:(CGPoint)pointInWindow wheelDelta:(CGSize)delta;
144- (NSWindow *)hostWindow;
145- (void)typeCharacter:(char)character modifiers:(NSEventModifierFlags)modifiers;
146- (void)typeCharacter:(char)character;
147- (void)setEventTimestampOffset:(NSTimeInterval)offset;
148@property (nonatomic, readonly) NSTimeInterval eventTimestamp;
149@end
150#endif
151
Note: See TracBrowser for help on using the repository browser.