Skip to content

Commit

Permalink
Remote Web Inspector: Send the presentingApplicationPID to the rela…
Browse files Browse the repository at this point in the history
…y process for WKWebViews

https://bugs.webkit.org/show_bug.cgi?id=254537
rdar://105636143

Reviewed by BJ Burg.

In some cases, a process may create WKWebViews on behalf of another process to be served remotely. WKWebViews
inspectability is managed in the UI process, and those does not currently use the `presentingApplicationPID` to
associate a target with a specific parent process (a process may represent multiple parent processes at a time). We thus
need to provide target-specific PIDs for the presenting application so that WKWebViews are correctly related back to the
application that is showing the web content via the intermediate remote service that actually created the WKWebView.

* Source/JavaScriptCore/inspector/remote/RemoteInspectionTarget.cpp:
(Inspector::RemoteInspectionTarget::setPresentingApplicationPID):
* Source/JavaScriptCore/inspector/remote/RemoteInspectionTarget.h:
- Allow setting a per-target `presentingApplicationPID` as an alternative to having a single PID the entire process
proxies its inspectable content to.

* Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorCocoa.mm:
(Inspector::identifierForPID):
(Inspector::RemoteInspector::listingForInspectionTarget const):
- Provide a per-target presenting application PID so that individual web views can be associated the appropriate process.
Relays should use this value in place of the application-wide parent process PID when it is present. For WKWebView,
those values will be equal by default unless explicitly set.

(Inspector::RemoteInspector::receivedProxyApplicationSetupMessage):
- Proxy apps don't need to respond to the proxy setup message, since all the necessary information will be provided with
the application's listing of targets.

* Source/WebKit/UIProcess/WebPageProxy.cpp:
- Use the `presentingApplicationPID` of the web content process pool to inform associate the inspectable page with the
correct parent application, since that is the pool that the content to be inspected will actually exist in. Unless it
has been overriden, this will be the PID of the UI process.

Canonical link: https://commits.webkit.org/262620@main
  • Loading branch information
patrickangle committed Apr 5, 2023
1 parent de96a0b commit d5d5bd3
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
Expand Up @@ -111,6 +111,14 @@ void RemoteInspectionTarget::unpauseForInitializedInspector()
RemoteInspector::singleton().setupCompleted(targetIdentifier());
}

void RemoteInspectionTarget::setPresentingApplicationPID(std::optional<ProcessID>&& pid)
{
m_presentingApplicationPID = pid;
#if PLATFORM(COCOA)
RemoteInspector::singleton().setUsePerTargetPresentingApplicationPIDs(true);
#endif
}

} // namespace Inspector

#endif // ENABLE(REMOTE_INSPECTOR)
Expand Up @@ -29,6 +29,7 @@

#include "JSRemoteInspector.h"
#include "RemoteControllableTarget.h"
#include <wtf/ProcessID.h>
#include <wtf/RetainPtr.h>
#include <wtf/TypeCasts.h>
#include <wtf/text/WTFString.h>
Expand Down Expand Up @@ -62,6 +63,9 @@ class JS_EXPORT_PRIVATE RemoteInspectionTarget : public RemoteControllableTarget
// RemoteControllableTarget overrides.
bool remoteControlAllowed() const final;

std::optional<ProcessID> presentingApplicationPID() const { return m_presentingApplicationPID; }
void setPresentingApplicationPID(std::optional<ProcessID>&&);

private:
enum class Inspectable : uint8_t {
Yes,
Expand All @@ -76,6 +80,8 @@ class JS_EXPORT_PRIVATE RemoteInspectionTarget : public RemoteControllableTarget
#if USE(CF)
RetainPtr<CFRunLoopRef> m_runLoop;
#endif

std::optional<ProcessID> m_presentingApplicationPID;
};

} // namespace Inspector
Expand Down
4 changes: 4 additions & 0 deletions Source/JavaScriptCore/inspector/remote/RemoteInspector.h
Expand Up @@ -159,6 +159,9 @@ class JS_EXPORT_PRIVATE RemoteInspector final
void setParentProcessInformation(ProcessID, RetainPtr<CFDataRef> auditData);
void setParentProcessInfomationIsDelayed();
std::optional<audit_token_t> parentProcessAuditToken();

void setUsePerTargetPresentingApplicationPIDs(bool usePerTargetPresentingApplicationPIDs) { m_usePerTargetPresentingApplicationPIDs = usePerTargetPresentingApplicationPIDs; }

bool isSimulatingCustomerInstall() const { return m_simulateCustomerInstall; }
#endif

Expand Down Expand Up @@ -308,6 +311,7 @@ class JS_EXPORT_PRIVATE RemoteInspector final
RetainPtr<CFDataRef> m_parentProcessAuditData;
bool m_messageDataTypeChunkSupported { false };
bool m_simulateCustomerInstall { false };
bool m_usePerTargetPresentingApplicationPIDs { false };
#endif
bool m_shouldSendParentProcessInformation { false };
bool m_automaticInspectionEnabled WTF_GUARDED_BY_LOCK(m_mutex) { false };
Expand Down
Expand Up @@ -453,6 +453,12 @@ static bool canAccessWebInspectorMachPort()

#pragma mark - Listings

static NSString* identifierForPID(ProcessID pid)
{
// This format matches that used in the relay process.
return [NSString stringWithFormat:@"PID:%lu", (unsigned long)pid];
}

RetainPtr<NSDictionary> RemoteInspector::listingForInspectionTarget(const RemoteInspectionTarget& target) const
{
// Must collect target information on the WebThread, Main, or Worker thread since RemoteTargets are
Expand Down Expand Up @@ -493,6 +499,9 @@ static bool canAccessWebInspectorMachPort()
break;
}

if (auto presentingApplicationPID = target.presentingApplicationPID())
[listing setObject:identifierForPID(presentingApplicationPID.value()) forKey:WIRHostApplicationIdentifierKey];

if (auto* connectionToTarget = m_targetConnectionMap.get(target.targetIdentifier()))
[listing setObject:connectionToTarget->connectionIdentifier() forKey:WIRConnectionIdentifierKey];

Expand Down Expand Up @@ -722,6 +731,11 @@ static bool canAccessWebInspectorMachPort()
if (!m_relayConnection)
return;

// Proxy applications using per-target `presentingApplicationPID`s do not require any additional setup. The remote
// relay will complete its setup when the inspectable target listing is sent to it.
if (m_usePerTargetPresentingApplicationPIDs)
return;

if (!m_parentProcessIdentifier || !m_parentProcessAuditData) {
// We are a proxy application without parent process information.
// Wait a bit for the information, but give up after a second.
Expand Down
1 change: 1 addition & 0 deletions Source/WebKit/UIProcess/WebPageProxy.cpp
Expand Up @@ -580,6 +580,7 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, Ref

#if ENABLE(REMOTE_INSPECTOR)
m_inspectorDebuggable->setInspectable(JSRemoteInspectorGetInspectionEnabledByDefault());
m_inspectorDebuggable->setPresentingApplicationPID(m_process->processPool().configuration().presentingApplicationPID());
m_inspectorDebuggable->init();
#endif
m_inspectorController->init();
Expand Down

0 comments on commit d5d5bd3

Please sign in to comment.