1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_COMMON_SERVICE_PROCESS_UTIL_H_
6 #define CHROME_COMMON_SERVICE_PROCESS_UTIL_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/callback_forward.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/read_only_shared_memory_region.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/writable_shared_memory_region.h"
16 #include "base/process/process.h"
17 #include "base/single_thread_task_runner.h"
18 #include "build/build_config.h"
19 #include "mojo/public/cpp/platform/named_platform_channel.h"
20 #include "mojo/public/cpp/platform/platform_channel_server_endpoint.h"
21 
22 class MultiProcessLock;
23 
24 namespace base {
25 class CommandLine;
26 }
27 
28 // Return the IPC channel to connect to the service process.
29 mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName();
30 
31 // Return a name that is scoped to this instance of the service process. We
32 // use the user-data-dir as a scoping prefix.
33 std::string GetServiceProcessScopedName(const std::string& append_str);
34 
35 #if !defined(OS_MAC)
36 // Return a name that is scoped to this instance of the service process. We
37 // use the user-data-dir and the version as a scoping prefix.
38 std::string GetServiceProcessScopedVersionedName(const std::string& append_str);
39 #endif  // !OS_MAC
40 
41 #if defined(OS_POSIX)
42 // Attempts to take a session-wide lock named name. Returns a non-null lock if
43 // successful.
44 std::unique_ptr<MultiProcessLock> TakeNamedLock(const std::string& name);
45 #endif
46 
47 // The following method is used in a process that acts as a client to the
48 // service process (typically the browser process). It method checks that if the
49 // service process is ready to receive IPC commands.
50 bool CheckServiceProcessReady();
51 
52 // --------------------------------------------------------------------------
53 
54 // Forces a service process matching the specified version to shut down.
55 bool ForceServiceProcessShutdown(const std::string& version,
56                                  base::ProcessId process_id);
57 
58 // Creates command-line to run the service process.
59 std::unique_ptr<base::CommandLine> CreateServiceProcessCommandLine();
60 
61 // This is a class that is used by the service process to signal events and
62 // share data with external clients. This class lives in this file because the
63 // internal data structures and mechanisms used by the utility methods above
64 // and this class are shared.
65 class ServiceProcessState {
66  public:
67   ServiceProcessState();
68   ~ServiceProcessState();
69 
70   // Tries to become the sole service process for the current user data dir.
71   // Returns false if another service process is already running.
72   bool Initialize();
73 
74   // Signal that the service process is ready.
75   // This method is called when the service process is running and initialized.
76   // |terminate_task| is invoked when we get a terminate request from another
77   // process (in the same thread that called SignalReady). It can be NULL.
78   // |task_runner| must be of type IO and is the loop that POSIX uses
79   // to monitor the service process.
80   bool SignalReady(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
81                    base::OnceClosure terminate_task);
82 
83   // Signal that the service process is stopped.
84   void SignalStopped();
85 
86   // Register the service process to run on startup.
87   bool AddToAutoRun();
88 
89   // Unregister the service process to run on startup.
90   bool RemoveFromAutoRun();
91 
92   // Return the channel handle used for communicating with the service.
93 #if defined(OS_MAC)
94   mojo::PlatformChannelServerEndpoint GetServiceProcessServerEndpoint();
95 #else
96   mojo::NamedPlatformChannel::ServerName GetServiceProcessServerName();
97 #endif
98 
99  private:
100 #if !defined(OS_MAC)
101   enum ServiceProcessRunningState {
102     SERVICE_NOT_RUNNING,
103     SERVICE_OLDER_VERSION_RUNNING,
104     SERVICE_SAME_VERSION_RUNNING,
105     SERVICE_NEWER_VERSION_RUNNING,
106   };
107 
108   // Create the shared memory data for the service process.
109   bool CreateSharedData();
110 
111   // If an older version of the service process running, it should be shutdown.
112   // Returns false if this process needs to exit.
113   bool HandleOtherVersion();
114 
115   // Acquires a singleton lock for the service process. A return value of false
116   // means that a service process instance is already running.
117   bool TakeSingletonLock();
118 
119   // Return a name used to name a shared memory file that will be used to locate
120   // the currently running service process.
121   static std::string GetServiceProcessSharedMemName();
122 
123   // Create a writable service process data shared memory region of the
124   // specified size. Returns an invalid region on error. If the backing file for
125   // the shared memory region already exists but is smaller than |size|, this
126   // function may return a valid region which will fail to be mapped.
127   static base::WritableSharedMemoryRegion CreateServiceProcessDataRegion(
128       size_t size);
129 
130   // Open an existing service process data shared memory region of the specified
131   // size. Returns an invalid region on error. Note that if the size of the
132   // existing region is smaller than |size|, this function may return a valid
133   // region which will fail to be mapped. Also note that since the underlying
134   // file is writable, the region cannot be read-only.
135   static base::ReadOnlySharedMemoryMapping OpenServiceProcessDataMapping(
136       size_t size);
137 
138   // Deletes a service process data shared memory backing file. Returns false if
139   // the file was not able to be deleted.
140   static bool DeleteServiceProcessDataRegion();
141 
142   static ServiceProcessRunningState GetServiceProcessRunningState(
143       std::string* service_version_out,
144       base::ProcessId* pid_out);
145 #endif  // !OS_MAC
146 
147   // Returns the process id and version of the currently running service
148   // process. Note: DO NOT use this check whether the service process is ready
149   // because a true return value only means that some process shared data was
150   // available, and not that the process is ready to receive IPC commands, or
151   // even running.
152   static bool GetServiceProcessData(std::string* version, base::ProcessId* pid);
153 
154   // Creates the platform specific state.
155   void CreateState();
156 
157   // Tear down the platform specific state.
158   void TearDownState();
159 
160   // An opaque object that maintains state. The actual definition of this is
161   // platform dependent.
162   struct StateData;
163   StateData* state_;
164 
165 #if !defined(OS_MAC)
166   // The shared memory mapping backing the shared state on non-macos
167   // platforms. This is actually referring to named shared memory, and on some
168   // platforms (eg, Windows) determines the lifetime of when consumers are able
169   // to open the named shared region. This means this region must stay alive
170   // for the named region to be visible.
171   base::WritableSharedMemoryRegion service_process_data_region_;
172 #endif
173 
174   std::unique_ptr<base::CommandLine> autorun_command_line_;
175 
176 #if defined(OS_MAC)
177   friend bool CheckServiceProcessReady();
178 #endif
179 
180   FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, SharedMem);
181   FRIEND_TEST_ALL_PREFIXES(ServiceProcessStateTest, ForceShutdown);
182 
183   friend class ServiceProcessControlBrowserTest;
184   FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, ForceShutdown);
185   FRIEND_TEST_ALL_PREFIXES(ServiceProcessControlBrowserTest, CheckPid);
186 };
187 
188 #endif  // CHROME_COMMON_SERVICE_PROCESS_UTIL_H_
189