1 // Copyright 2019 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 CONTENT_PUBLIC_BROWSER_SERVICE_PROCESS_HOST_H_ 6 #define CONTENT_PUBLIC_BROWSER_SERVICE_PROCESS_HOST_H_ 7 8 #include <memory> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/command_line.h" 14 #include "base/macros.h" 15 #include "base/observer_list.h" 16 #include "base/optional.h" 17 #include "base/strings/string16.h" 18 #include "base/strings/string_piece.h" 19 #include "content/common/content_export.h" 20 #include "content/public/browser/sandbox_type.h" 21 #include "content/public/browser/service_process_info.h" 22 #include "mojo/public/cpp/bindings/generic_pending_receiver.h" 23 #include "mojo/public/cpp/bindings/pending_receiver.h" 24 #include "mojo/public/cpp/bindings/remote.h" 25 #include "mojo/public/cpp/system/message_pipe.h" 26 27 namespace content { 28 29 // ServiceProcessHost is used to launch new service processes given basic 30 // parameters like sandbox type, as well as a primordial Mojo interface to drive 31 // the service's behavior. See |Launch()| methods below for more details. 32 // 33 // Typical usage might look something like: 34 // 35 // constexpr auto kFooServiceIdleTimeout = base::TimeDelta::FromSeconds(5); 36 // auto foo_service = ServiceProcessHost::Launch<foo::mojom::FooService>( 37 // ServiceProcessHost::Options() 38 // .WithSandboxType(SandboxType::kUtility) 39 // .WithDisplayName(IDS_FOO_SERVICE_DISPLAY_NAME) 40 // .Pass()); 41 // foo_service.set_idle_handler( 42 // kFooServiceIdleTimeout, 43 // base::BindRepeating( 44 // /* Something to reset |foo_service|, killing the process. */)); 45 // foo_service->DoWork(); 46 // 47 class CONTENT_EXPORT ServiceProcessHost { 48 public: 49 struct CONTENT_EXPORT Options { 50 Options(); 51 ~Options(); 52 53 Options(Options&&); 54 55 // Specifies the sandbox type with which to launch the service process. 56 // Defaults to a generic, restrictive utility process sandbox. 57 Options& WithSandboxType(SandboxType type); 58 59 // Specifies the display name of the service process. This should generally 60 // be a human readable and meaningful application or service name and will 61 // appear in places like the system task viewer. 62 Options& WithDisplayName(const std::string& name); 63 Options& WithDisplayName(const base::string16& name); 64 Options& WithDisplayName(int resource_id); 65 66 // Specifies additional flags to configure the launched process. See 67 // ChildProcessHost for flag definitions. 68 Options& WithChildFlags(int flags); 69 70 // Specifies extra command line switches to append before launch. 71 Options& WithExtraCommandLineSwitches(std::vector<std::string> switches); 72 73 // Passes the contents of this Options object to a newly returned Options 74 // value. This must be called when moving a built Options object into a call 75 // to |Launch()|. 76 Options Pass(); 77 78 SandboxType sandbox_type = SandboxType::kUtility; 79 base::string16 display_name; 80 base::Optional<int> child_flags; 81 std::vector<std::string> extra_switches; 82 }; 83 84 // An interface which can be implemented and registered/unregistered with 85 // |Add/RemoveObserver()| below to watch for all service process creation and 86 // and termination events globally. Methods are always called from the UI 87 // UI thread. 88 class CONTENT_EXPORT Observer : public base::CheckedObserver { 89 public: ~Observer()90 ~Observer() override {} 91 OnServiceProcessLaunched(const ServiceProcessInfo & info)92 virtual void OnServiceProcessLaunched(const ServiceProcessInfo& info) {} OnServiceProcessTerminatedNormally(const ServiceProcessInfo & info)93 virtual void OnServiceProcessTerminatedNormally( 94 const ServiceProcessInfo& info) {} OnServiceProcessCrashed(const ServiceProcessInfo & info)95 virtual void OnServiceProcessCrashed(const ServiceProcessInfo& info) {} 96 }; 97 98 // Launches a new service process for asks it to bind the given interface 99 // receiver. |Interface| must be a service interface known to utility process 100 // code. See content/utility/services.cc and/or 101 // ContentUtilityClient::Run{Main,IO}ThreadService() methods. 102 // 103 // The launched process will (disregarding crashes) stay alive until either 104 // end of the |Interface| pipe is closed. Typically services are designed to 105 // never close their end of this pipe, and it's up to the browser to 106 // explicitly reset its corresponding Remote in order to induce service 107 // process termination. 108 // 109 // NOTE: The |Interface| type can be inferred from from the |receiver| 110 // argument's type. 111 // 112 // May be called from any thread. 113 template <typename Interface> 114 static void Launch(mojo::PendingReceiver<Interface> receiver, 115 Options options = {}) { 116 Launch(mojo::GenericPendingReceiver(std::move(receiver)), 117 std::move(options)); 118 } 119 120 // Same as above but creates a new |Interface| pipe on the caller's behalf and 121 // returns its Remote endpoint. 122 // 123 // May be called from any thread. 124 template <typename Interface> 125 static mojo::Remote<Interface> Launch(Options options = {}) { 126 mojo::Remote<Interface> remote; 127 Launch(remote.BindNewPipeAndPassReceiver(), std::move(options)); 128 return remote; 129 } 130 131 // Yields information about currently active service processes. Must be called 132 // from the UI Thread only. 133 static std::vector<ServiceProcessInfo> GetRunningProcessInfo(); 134 135 // Registers a global observer of all service process lifetimes. Must be 136 // removed before destruction. Must be called from the UI thread only. 137 static void AddObserver(Observer* observer); 138 139 // Removes a registered observer. This must be called some time before 140 // |*observer| is destroyed and must be called from the UI thread only. 141 static void RemoveObserver(Observer* observer); 142 143 private: 144 // Launches a new service process and asks it to bind a receiver for the 145 // service interface endpoint carried by |receiver|, which should be connected 146 // to a Remote of the same interface type. 147 static void Launch(mojo::GenericPendingReceiver receiver, Options options); 148 }; 149 150 } // namespace content 151 152 #endif // CONTENT_PUBLIC_BROWSER_SERVICE_PROCESS_HOST_H_ 153