Hide password echo when screen is being captured.
authormegan_gardner@apple.com <megan_gardner@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 May 2020 22:33:59 +0000 (22:33 +0000)
committermegan_gardner@apple.com <megan_gardner@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 May 2020 22:33:59 +0000 (22:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212060
<rdar://problem/47653578>

Reviewed by Wenson Hsieh.

Source/WebCore:

When the screen is being captured, turn off the password echo.

* editing/InsertIntoTextNodeCommand.cpp:
(WebCore::InsertIntoTextNodeCommand::doApply):
* page/EditorClient.h:
(WebCore::EditorClient::isScreenCaptured const):

Source/WebKit:

Use the UIScreen state and notification to determine if the
screen is being shared or captured. This flag is for all
capture methods, Air Play, Screen Recording, etc. If the screen is
being captured, turn off the password echo to prevent the password from
being leaked.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _commonInitializationWithProcessPool:configuration:]):
(-[WKContentView _screenCapturedDidChange:]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setIsScreenCaptured):
* WebProcess/WebCoreSupport/WebEditorClient.h:
* WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
(WebKit::WebEditorClient::isScreenCaptured const):
* WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::isScreenCaptured const):
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setIsScreenCaptured):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261966 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/WebCore/ChangeLog
Source/WebCore/editing/InsertIntoTextNodeCommand.cpp
Source/WebCore/page/EditorClient.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPageCreationParameters.cpp
Source/WebKit/Shared/WebPageCreationParameters.h
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/WKContentView.mm
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebProcess/WebCoreSupport/WebEditorClient.h
Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKitLegacy/ios/DefaultDelegates/WebDefaultUIKitDelegate.m
Source/WebKitLegacy/ios/WebView/WebUIKitDelegate.h
Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.h
Source/WebKitLegacy/mac/WebCoreSupport/WebEditorClient.mm
Source/WebKitLegacy/mac/WebView/WebView.mm
Source/WebKitLegacy/mac/WebView/WebViewData.h

index 62b3b45..5ddc981 100644 (file)
@@ -1,3 +1,18 @@
+2020-05-20  Megan Gardner  <megan_gardner@apple.com>
+
+        Hide password echo when screen is being captured.
+        https://bugs.webkit.org/show_bug.cgi?id=212060
+        <rdar://problem/47653578>
+
+        Reviewed by Wenson Hsieh.
+
+        When the screen is being captured, turn off the password echo. 
+
+        * editing/InsertIntoTextNodeCommand.cpp:
+        (WebCore::InsertIntoTextNodeCommand::doApply):
+        * page/EditorClient.h:
+        (WebCore::EditorClient::isScreenCaptured const):
+
 2020-05-20  ChangSeok Oh  <changseok@webkit.org>
 
         [GTK] Implement connected and disconnected events of GAMEPAD API with libmanette
index 6601db8..4046530 100644 (file)
@@ -27,6 +27,8 @@
 #include "InsertIntoTextNodeCommand.h"
 
 #include "Document.h"
+#include "Editor.h"
+#include "EditorClient.h"
 #include "Frame.h"
 #include "RenderText.h"
 #include "Settings.h"
@@ -51,13 +53,14 @@ InsertIntoTextNodeCommand::InsertIntoTextNodeCommand(Ref<Text>&& node, unsigned
 void InsertIntoTextNodeCommand::doApply()
 {
     bool passwordEchoEnabled = document().settings().passwordEchoEnabled();
-    if (passwordEchoEnabled)
+    bool shouldSuppressPasswordEcho = document().editor().client()->shouldSuppressPasswordEcho();
+    if (passwordEchoEnabled && !shouldSuppressPasswordEcho)
         document().updateLayoutIgnorePendingStylesheets();
 
     if (!m_node->hasEditableStyle())
         return;
 
-    if (passwordEchoEnabled) {
+    if (passwordEchoEnabled && !shouldSuppressPasswordEcho) {
         if (RenderText* renderText = m_node->renderer())
             renderText->momentarilyRevealLastTypedCharacter(m_offset + m_text.length());
     }
index 584b1e4..7793171 100644 (file)
@@ -71,6 +71,7 @@ public:
     virtual bool shouldInsertText(const String&, Range*, EditorInsertAction) = 0;
     virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting) = 0;
     virtual bool shouldRevealCurrentSelectionAfterInsertion() const { return true; };
+    virtual bool shouldSuppressPasswordEcho() const { return false; };
     
     virtual bool shouldApplyStyle(StyleProperties*, Range*) = 0;
     virtual void didApplyStyle() = 0;
index c92d778..cee20cc 100644 (file)
@@ -1,3 +1,32 @@
+2020-05-20  Megan Gardner  <megan_gardner@apple.com>
+
+        Hide password echo when screen is being captured.
+        https://bugs.webkit.org/show_bug.cgi?id=212060
+        <rdar://problem/47653578>
+
+        Reviewed by Wenson Hsieh.
+
+        Use the UIScreen state and notification to determine if the
+        screen is being shared or captured. This flag is for all
+        capture methods, Air Play, Screen Recording, etc. If the screen is
+        being captured, turn off the password echo to prevent the password from
+        being leaked.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _commonInitializationWithProcessPool:configuration:]):
+        (-[WKContentView _screenCapturedDidChange:]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setIsScreenCaptured):
+        * WebProcess/WebCoreSupport/WebEditorClient.h:
+        * WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
+        (WebKit::WebEditorClient::isScreenCaptured const):
+        * WebProcess/WebPage/WebPage.h:
+        (WebKit::WebPage::isScreenCaptured const):
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setIsScreenCaptured):
+
 2020-05-20  ChangSeok Oh  <changseok@webkit.org>
 
         [GTK] Implement connected and disconnected events of GAMEPAD API with libmanette
index 8c80de2..a1c6d16 100644 (file)
@@ -107,6 +107,7 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
     encoder << deviceOrientation;
     encoder << keyboardIsAttached;
     encoder << canShowWhileLocked;
+    encoder << isCapturingScreen;
 #endif
 #if PLATFORM(COCOA)
     encoder << smartInsertDeleteEnabled;
@@ -340,6 +341,8 @@ Optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::Decod
         return WTF::nullopt;
     if (!decoder.decode(parameters.canShowWhileLocked))
         return WTF::nullopt;
+    if (!decoder.decode(parameters.isCapturingScreen))
+        return WTF::nullopt;
 #endif
 
 #if PLATFORM(COCOA)
index cff3135..341e4de 100644 (file)
@@ -167,6 +167,7 @@ struct WebPageCreationParameters {
     int32_t deviceOrientation { 0 };
     bool keyboardIsAttached { false };
     bool canShowWhileLocked { false };
+    bool isCapturingScreen { false };
 #endif
 #if PLATFORM(COCOA)
     bool smartInsertDeleteEnabled;
index d0b7d66..c97952d 100644 (file)
@@ -718,6 +718,8 @@ public:
     void focusTextInputContextAndPlaceCaret(const WebCore::ElementContext&, const WebCore::IntPoint&, CompletionHandler<void(bool)>&&);
 
     void setShouldRevealCurrentSelectionAfterInsertion(bool);
+        
+    void setScreenIsBeingCaptured(bool);
 
     void insertTextPlaceholder(const WebCore::IntSize&, CompletionHandler<void(const Optional<WebCore::ElementContext>&)>&&);
     void removeTextPlaceholder(const WebCore::ElementContext&, CompletionHandler<void()>&&);
index 2d79cef..6cecb11 100644 (file)
@@ -169,6 +169,7 @@ static NSArray *keyCommandsPlaceholderHackForEvernote(id self, SEL _cmd)
     _page->setIntrinsicDeviceScaleFactor(WebCore::screenScaleFactor([UIScreen mainScreen]));
     _page->setUseFixedLayout(true);
     _page->setDelegatesScrolling(true);
+    _page->setScreenIsBeingCaptured([[[self window] screen] isCaptured]);
 
 #if ENABLE(FULLSCREEN_API)
     _page->setFullscreenClient(makeUnique<WebKit::FullscreenClient>(self.webView));
@@ -208,6 +209,7 @@ static NSArray *keyCommandsPlaceholderHackForEvernote(id self, SEL _cmd)
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_screenCapturedDidChange:) name:UIScreenCapturedDidChangeNotification object:[UIScreen mainScreen]];
 
 #if USE(UIKIT_KEYBOARD_ADDITIONS)
     if (WebCore::IOSApplication::isEvernote() && !linkedOnOrAfter(WebKit::SDKVersion::FirstWhereWKContentViewDoesNotOverrideKeyCommands))
@@ -771,6 +773,11 @@ static void storeAccessibilityRemoteConnectionInformation(id element, pid_t pid,
         _page->applicationWillEnterForegroundForMedia();
 }
 
+- (void)_screenCapturedDidChange:(NSNotification *)notification
+{
+    _page->setScreenIsBeingCaptured([[[self window] screen] isCaptured]);
+}
+
 @end
 
 #pragma mark Printing
index 4f707d1..6acf8e8 100644 (file)
@@ -896,6 +896,7 @@ static WKDragSessionContext *ensureLocalDragSessionContext(id <UIDragSession> se
 #endif
 
     _page->process().updateTextCheckerState();
+    _page->setScreenIsBeingCaptured([[[self window] screen] isCaptured]);
 
     _hasSetUpInteractions = YES;
 }
index 9ba0f8f..165ebf1 100644 (file)
@@ -1581,6 +1581,12 @@ void WebPageProxy::setShouldRevealCurrentSelectionAfterInsertion(bool shouldReve
         send(Messages::WebPage::SetShouldRevealCurrentSelectionAfterInsertion(shouldRevealCurrentSelectionAfterInsertion));
 }
 
+void WebPageProxy::setScreenIsBeingCaptured(bool captured)
+{
+    if (hasRunningProcess())
+        send(Messages::WebPage::SetScreenIsBeingCaptured(captured));
+}
+
 void WebPageProxy::willOpenAppLink()
 {
     if (m_openingAppLinkActivity && m_openingAppLinkActivity->isValid())
index 0d62f73..0df7759 100644 (file)
@@ -188,6 +188,7 @@ private:
     void updateStringForFind(const String&) final;
     bool shouldAllowSingleClickToChangeSelection(WebCore::Node&, const WebCore::VisibleSelection&) const final;
     bool shouldRevealCurrentSelectionAfterInsertion() const final;
+    bool shouldSuppressPasswordEcho() const final;
 #endif
 
     bool performTwoStepDrop(WebCore::DocumentFragment&, WebCore::Range&, bool isMove) final;
index 8f7ff07..afb3861 100644 (file)
@@ -119,6 +119,11 @@ bool WebEditorClient::shouldRevealCurrentSelectionAfterInsertion() const
     return m_page->shouldRevealCurrentSelectionAfterInsertion();
 }
 
+bool WebEditorClient::shouldSuppressPasswordEcho() const
+{
+    return m_page->screenIsBeingCaptured() || m_page->hardwareKeyboardIsAttached();
+}
+
 } // namespace WebKit
 
 #endif // PLATFORM(IOS_FAMILY)
index d626828..7b264bb 100644 (file)
@@ -667,6 +667,9 @@ public:
     WebCore::FloatSize overrideScreenSize() const;
     int32_t deviceOrientation() const { return m_deviceOrientation; }
     void didReceiveMobileDocType(bool);
+    
+    bool screenIsBeingCaptured() const { return m_screenIsBeingCaptured; }
+    void setScreenIsBeingCaptured(bool);
 
     double minimumPageScaleFactor() const;
     double maximumPageScaleFactor() const;
@@ -1016,6 +1019,7 @@ public:
     bool platformPrefersTextLegibilityBasedZoomScaling() const;
 
     void hardwareKeyboardAvailabilityChanged(bool keyboardIsAttached);
+    bool hardwareKeyboardIsAttached() const { return m_keyboardIsAttached; }
 
     void updateStringForFind(const String&);
     
@@ -1990,6 +1994,7 @@ private:
     bool m_hasStablePageScaleFactor { true };
     bool m_isInStableState { true };
     bool m_shouldRevealCurrentSelectionAfterInsertion { true };
+    bool m_screenIsBeingCaptured { false };
     MonotonicTime m_oldestNonStableUpdateVisibleContentRectsTimestamp;
     Seconds m_estimatedLatency { 0 };
     WebCore::FloatSize m_screenSize;
index 2aadefe..538e657 100644 (file)
@@ -52,6 +52,8 @@ messages -> WebPage LegacyReceiver {
     SetDeviceOrientation(int32_t deviceOrientation)
     SetOverrideViewportArguments(Optional<WebCore::ViewportArguments> arguments)
     DynamicViewportSizeUpdate(WebCore::FloatSize viewLayoutSize, WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, WebCore::RectEdges<float> targetUnobscuredSafeAreaInsets, double scale, int32_t deviceOrientation, double minimumEffectiveDeviceWidth, uint64_t dynamicViewportSizeUpdateID)
+    
+    SetScreenIsBeingCaptured(bool captured)
 
     HandleTap(WebCore::IntPoint point, OptionSet<WebKit::WebEvent::Modifier> modifiers, WebKit::TransactionID lastLayerTreeTransactionId)
     PotentialTapAtPosition(uint64_t requestID, WebCore::FloatPoint point, bool shouldRequestMagnificationInformation)
index 3859922..9aef42b 100644 (file)
@@ -4292,6 +4292,11 @@ void WebPage::setShouldRevealCurrentSelectionAfterInsertion(bool shouldRevealCur
     scheduleFullEditorStateUpdate();
 }
 
+void WebPage::setScreenIsBeingCaptured(bool captured)
+{
+    m_screenIsBeingCaptured = captured;
+}
+
 void WebPage::textInputContextsInRect(FloatRect searchRect, CompletionHandler<void(const Vector<ElementContext>&)>&& completionHandler)
 {
     auto contexts = m_page->editableElementsInRect(searchRect).map([&] (const auto& element) {
index 0be80fb..3e7b818 100644 (file)
@@ -268,6 +268,11 @@ static WebDefaultUIKitDelegate *sharedDelegate = nil;
 }
 #endif
 
+- (BOOL)shouldSuppressPasswordEcho
+{
+    return NO;
+}
+
 - (BOOL)hasRichlyEditableSelection
 {
     return NO;
index 51698cc..c664ea6 100644 (file)
@@ -128,6 +128,8 @@ typedef NS_ENUM(NSInteger, WebMediaCaptureType) {
 
 - (BOOL)shouldRevealCurrentSelectionAfterInsertion;
 
+- (BOOL)shouldSuppressPasswordEcho;
+
 #if ENABLE_ORIENTATION_EVENTS
 - (int)deviceOrientation;
 #endif
index 8456f26..e1b42ea 100644 (file)
@@ -149,8 +149,8 @@ private:
     RefPtr<WebCore::DocumentFragment> documentFragmentFromDelegate(int index) final;
     bool performsTwoStepPaste(WebCore::DocumentFragment*) final;
     void updateStringForFind(const String&) final { }
-
     bool shouldRevealCurrentSelectionAfterInsertion() const final;
+    bool shouldSuppressPasswordEcho() const final;
 #endif
 
     bool performTwoStepDrop(WebCore::DocumentFragment&, WebCore::Range& destination, bool isMove) final;
index 4c218cd..d066411 100644 (file)
@@ -830,6 +830,13 @@ bool WebEditorClient::shouldRevealCurrentSelectionAfterInsertion() const
     return true;
 }
 
+bool WebEditorClient::shouldSuppressPasswordEcho() const
+{
+    if ([[m_webView _UIKitDelegateForwarder] respondsToSelector:@selector(shouldSuppressPasswordEcho)])
+        return [[m_webView _UIKitDelegateForwarder] shouldSuppressPasswordEcho];
+    return false;
+}
+
 RefPtr<WebCore::DocumentFragment> WebEditorClient::documentFragmentFromDelegate(int index)
 {
     if ([[m_webView _editingDelegateForwarder] respondsToSelector:@selector(documentFragmentForPasteboardItemAtIndex:)]) {
index 5db5f25..adce904 100644 (file)
@@ -1525,6 +1525,8 @@ static void WebKitInitializeGamepadProviderIfNecessary()
 #if ENABLE(ORIENTATION_EVENTS)
     _private->deviceOrientation = [[self _UIKitDelegateForwarder] deviceOrientation];
 #endif
+    if ([[self _UIKitDelegateForwarder] respondsToSelector:@selector(shouldSuppressPasswordEcho)])
+        _private->shouldSuppressPasswordEcho = [[self _UIKitDelegateForwarder] shouldSuppressPasswordEcho];
 #endif
 
     if ([[NSUserDefaults standardUserDefaults] objectForKey:WebSmartInsertDeleteEnabled])
index ae8add4..a028d77 100644 (file)
@@ -245,6 +245,7 @@ private:
 #if ENABLE(ORIENTATION_EVENTS)
     NSUInteger deviceOrientation;
 #endif
+    BOOL shouldSuppressPasswordEcho;
 #endif
     BOOL shouldCloseWithWindow;
     BOOL mainFrameDocumentReady;