1/*
2 * Copyright (C) 2010-2019 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#pragma once
27
28#include "Connection.h"
29#include "MessageReceiverMap.h"
30#include "MessageSender.h"
31#include <WebCore/ProcessIdentifier.h>
32#include <WebCore/UserActivity.h>
33#include <wtf/HashMap.h>
34#include <wtf/RunLoop.h>
35#include <wtf/text/StringHash.h>
36#include <wtf/text/WTFString.h>
37
38namespace WebKit {
39
40class SandboxInitializationParameters;
41struct AuxiliaryProcessInitializationParameters;
42
43class AuxiliaryProcess : protected IPC::Connection::Client, public IPC::MessageSender {
44 WTF_MAKE_NONCOPYABLE(AuxiliaryProcess);
45
46public:
47 enum class ProcessType : uint8_t {
48 WebContent,
49 Network,
50 Plugin
51 };
52
53 void initialize(const AuxiliaryProcessInitializationParameters&);
54
55 // disable and enable termination of the process. when disableTermination is called, the
56 // process won't terminate unless a corresponding disableTermination call is made.
57 void disableTermination();
58 void enableTermination();
59
60 void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&);
61 void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&);
62 void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID);
63 void removeMessageReceiver(IPC::StringReference messageReceiverName);
64 void removeMessageReceiver(IPC::MessageReceiver&);
65
66 template <typename T>
67 void addMessageReceiver(IPC::StringReference messageReceiverName, ObjectIdentifier<T> destinationID, IPC::MessageReceiver& receiver)
68 {
69 addMessageReceiver(messageReceiverName, destinationID.toUInt64(), receiver);
70 }
71
72 template <typename T>
73 void removeMessageReceiver(IPC::StringReference messageReceiverName, ObjectIdentifier<T> destinationID)
74 {
75 removeMessageReceiver(messageReceiverName, destinationID.toUInt64());
76 }
77
78 void setProcessSuppressionEnabled(bool);
79
80#if PLATFORM(COCOA)
81 void setApplicationIsDaemon();
82 void launchServicesCheckIn();
83 void setQOS(int latencyQOS, int throughputQOS);
84#endif
85
86 IPC::Connection* parentProcessConnection() const { return m_connection.get(); }
87
88 IPC::MessageReceiverMap& messageReceiverMap() { return m_messageReceiverMap; }
89
90#if PLATFORM(MAC)
91 static bool isSystemWebKit();
92#endif
93
94#if PLATFORM(COCOA)
95 bool parentProcessHasEntitlement(const char* entitlement);
96#endif
97
98protected:
99 explicit AuxiliaryProcess();
100 virtual ~AuxiliaryProcess();
101
102 void setTerminationTimeout(Seconds seconds) { m_terminationTimeout = seconds; }
103
104 virtual void initializeProcess(const AuxiliaryProcessInitializationParameters&);
105 virtual void initializeProcessName(const AuxiliaryProcessInitializationParameters&);
106 virtual void initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&);
107 virtual void initializeConnection(IPC::Connection*);
108
109 virtual bool shouldTerminate() = 0;
110 virtual void terminate();
111
112 virtual void stopRunLoop();
113
114#if USE(APPKIT)
115 static void stopNSAppRunLoop();
116#endif
117
118#if PLATFORM(MAC) && ENABLE(WEBPROCESS_NSRUNLOOP)
119 static void stopNSRunLoop();
120#endif
121
122 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
123
124 void registerURLSchemeServiceWorkersCanHandle(const String&) const;
125#if OS(LINUX)
126 void didReceiveMemoryPressureEvent(bool isCritical);
127#endif
128
129private:
130 virtual bool shouldOverrideQuarantine() { return true; }
131
132 // IPC::MessageSender
133 IPC::Connection* messageSenderConnection() const override;
134 uint64_t messageSenderDestinationID() const override;
135
136 // IPC::Connection::Client.
137 void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) final;
138 void didClose(IPC::Connection&) override;
139
140 void shutDown();
141
142 void terminationTimerFired();
143
144 void platformInitialize();
145 void platformStopRunLoop();
146
147 // The timeout, in seconds, before this process will be terminated if termination
148 // has been enabled. If the timeout is 0 seconds, the process will be terminated immediately.
149 Seconds m_terminationTimeout;
150
151 // A termination counter; when the counter reaches zero, the process will be terminated
152 // after a given period of time.
153 unsigned m_terminationCounter;
154
155 RunLoop::Timer<AuxiliaryProcess> m_terminationTimer;
156
157 RefPtr<IPC::Connection> m_connection;
158 IPC::MessageReceiverMap m_messageReceiverMap;
159
160 UserActivity m_processSuppressionDisabled;
161
162#if PLATFORM(COCOA)
163 OSObjectPtr<xpc_object_t> m_priorityBoostMessage;
164#endif
165};
166
167struct AuxiliaryProcessInitializationParameters {
168 String uiProcessName;
169 String clientIdentifier;
170 Optional<WebCore::ProcessIdentifier> processIdentifier;
171 IPC::Connection::Identifier connectionIdentifier;
172 HashMap<String, String> extraInitializationData;
173 AuxiliaryProcess::ProcessType processType;
174#if PLATFORM(COCOA)
175 OSObjectPtr<xpc_object_t> priorityBoostMessage;
176#endif
177};
178
179} // namespace WebKit
180
181