Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 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 #include "chrome/app/mash/mash_runner.h" | |
| 6 | |
| 7 #include "ash/mus/sysui_application.h" | |
| 8 #include "base/at_exit.h" | |
| 9 #include "base/bind.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/debug/debugger.h" | |
| 12 #include "base/i18n/icu_util.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/message_loop/message_loop.h" | |
| 15 #include "base/process/launch.h" | |
| 16 #include "components/mus/mus_app.h" | |
| 17 #include "components/resource_provider/resource_provider_app.h" | |
| 18 #include "content/public/common/content_switches.h" | |
| 19 #include "mash/quick_launch/quick_launch_application.h" | |
| 20 #include "mash/shell/shell_application_delegate.h" | |
| 21 #include "mash/wm/window_manager_application.h" | |
| 22 #include "mojo/common/mojo_scheme_register.h" | |
| 23 #include "mojo/public/cpp/bindings/weak_binding_set.h" | |
| 24 #include "mojo/shell/background/background_shell.h" | |
| 25 #include "mojo/shell/public/cpp/shell_client.h" | |
| 26 #include "mojo/shell/public/cpp/shell_connection.h" | |
| 27 #include "mojo/shell/public/interfaces/shell_client_factory.mojom.h" | |
| 28 #include "mojo/shell/runner/common/switches.h" | |
| 29 #include "mojo/shell/runner/host/child_process_base.h" | |
| 30 #include "mojo/shell/runner/host/command_line_switch.h" | |
| 31 #include "url/gurl.h" | |
| 32 #include "url/url_util.h" | |
| 33 | |
| 34 #if defined(OS_LINUX) | |
| 35 #include "components/font_service/font_service_app.h" | |
| 36 #endif | |
| 37 | |
| 38 using mojo::shell::mojom::ShellClientFactory; | |
| 39 | |
| 40 namespace { | |
| 41 | |
| 42 // kProcessType used to identify child processes. | |
| 43 const char* kMashChild = "mash-child"; | |
| 44 | |
| 45 // ShellClient responsible for starting the appropriate app. | |
| 46 class DefaultShellClient : public mojo::ShellClient, | |
| 47 public ShellClientFactory, | |
| 48 public mojo::InterfaceFactory<ShellClientFactory> { | |
| 49 public: | |
| 50 DefaultShellClient() {} | |
| 51 ~DefaultShellClient() override {} | |
| 52 | |
| 53 // mojo::ShellClient: | |
| 54 bool AcceptConnection(mojo::Connection* connection) override { | |
| 55 connection->AddInterface<ShellClientFactory>(this); | |
| 56 return true; | |
| 57 } | |
| 58 | |
| 59 // mojo::InterfaceFactory<ShellClientFactory> | |
| 60 void Create(mojo::Connection* connection, | |
| 61 mojo::InterfaceRequest<ShellClientFactory> request) override { | |
| 62 shell_client_factory_bindings_.AddBinding(this, std::move(request)); | |
| 63 } | |
| 64 | |
| 65 // ShellClientFactory: | |
| 66 void CreateShellClient(mojo::shell::mojom::ShellClientRequest request, | |
| 67 const mojo::String& mojo_url) override { | |
| 68 const GURL url = GURL(std::string(mojo_url)); | |
|
Ben Goodger (Google)
2016/02/22 20:20:00
what's the purpose of converting to a URL here? yo
sky
2016/02/23 00:01:33
As mentioned in person so that cannonicalization w
| |
| 69 if (shell_client_) { | |
| 70 LOG(ERROR) << "request to create additional app " << url; | |
| 71 return; | |
| 72 } | |
| 73 shell_client_ = CreateShellClient(url); | |
| 74 if (shell_client_) { | |
| 75 shell_connection_.reset( | |
| 76 new mojo::ShellConnection(shell_client_.get(), std::move(request))); | |
| 77 return; | |
| 78 } | |
| 79 LOG(ERROR) << "unknown url " << url; | |
| 80 NOTREACHED(); | |
| 81 } | |
| 82 | |
| 83 private: | |
| 84 // TODO(sky): move this into mash. | |
| 85 scoped_ptr<mojo::ShellClient> CreateShellClient(const GURL& url) { | |
| 86 if (url == GURL("mojo:ash_sysui")) | |
| 87 return make_scoped_ptr(new ash::sysui::SysUIApplication); | |
| 88 if (url == GURL("mojo:desktop_wm")) | |
| 89 return make_scoped_ptr(new mash::wm::WindowManagerApplication); | |
| 90 if (url == GURL("mojo:mash_shell")) | |
| 91 return make_scoped_ptr(new mash::shell::ShellApplicationDelegate); | |
| 92 if (url == GURL("mojo:mus")) | |
| 93 return make_scoped_ptr(new mus::MandolineUIServicesApp); | |
| 94 if (url == GURL("mojo:quick_launch")) | |
| 95 return make_scoped_ptr(new mash::quick_launch::QuickLaunchApplication); | |
| 96 if (url == GURL("mojo:resource_provider")) { | |
| 97 return make_scoped_ptr( | |
| 98 new resource_provider::ResourceProviderApp("mojo:resource_provider")); | |
| 99 } | |
| 100 #if defined(OS_LINUX) | |
| 101 if (url == GURL("mojo:font_service")) | |
| 102 return make_scoped_ptr(new font_service::FontServiceApp); | |
| 103 #endif | |
| 104 return nullptr; | |
| 105 } | |
| 106 | |
| 107 mojo::WeakBindingSet<ShellClientFactory> shell_client_factory_bindings_; | |
| 108 scoped_ptr<mojo::ShellClient> shell_client_; | |
| 109 scoped_ptr<mojo::ShellConnection> shell_connection_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(DefaultShellClient); | |
| 112 }; | |
| 113 | |
| 114 bool IsChild() { | |
| 115 return base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 116 switches::kProcessType) && | |
| 117 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 118 switches::kProcessType) == kMashChild; | |
| 119 } | |
| 120 | |
| 121 } // namespace | |
| 122 | |
| 123 MashRunner::MashRunner() {} | |
| 124 | |
| 125 MashRunner::~MashRunner() {} | |
| 126 | |
| 127 void MashRunner::Run() { | |
| 128 if (IsChild()) | |
| 129 RunChild(); | |
| 130 else | |
| 131 RunMain(); | |
| 132 } | |
| 133 | |
| 134 void MashRunner::RunMain() { | |
| 135 // TODO(sky): refactor backgroundshell so can supply own context, we | |
| 136 // shouldn't we using context as it has a lot of stuff we don't really want | |
| 137 // in chrome. | |
| 138 mojo::shell::BackgroundShell background_shell; | |
| 139 std::vector<mojo::shell::CommandLineSwitch> additional_command_line_switches( | |
| 140 1); | |
| 141 additional_command_line_switches[0].key = switches::kProcessType; | |
| 142 additional_command_line_switches[0].value = kMashChild; | |
| 143 #if defined(OS_WIN) | |
| 144 mojo::shell::CommandLineSwitch prefetch_switch; | |
| 145 prefetch_switch.is_switch = false; | |
| 146 prefetch_switch.key = switches::kPrefetchArgumentOther; | |
| 147 additional_command_line_switches.emplace_back(prefetch_switch); | |
| 148 #endif | |
| 149 background_shell.Init(additional_command_line_switches); | |
| 150 shell_client_.reset(new DefaultShellClient); | |
| 151 shell_connection_.reset(new mojo::ShellConnection( | |
| 152 shell_client_.get(), | |
| 153 background_shell.CreateShellClientRequest(GURL("exe:chrome")))); | |
| 154 shell_connection_->WaitForInitialize(); | |
| 155 static_cast<mojo::Shell*>(shell_connection_.get()) | |
| 156 ->Connect("mojo:mash_shell"); | |
| 157 base::MessageLoop::current()->Run(); | |
| 158 } | |
| 159 | |
| 160 void MashRunner::RunChild() { | |
| 161 base::i18n::InitializeICU(); | |
| 162 mojo::shell::ChildProcessMain( | |
| 163 base::Bind(&MashRunner::StartChildApp, base::Unretained(this))); | |
| 164 } | |
| 165 | |
| 166 void MashRunner::StartChildApp( | |
| 167 mojo::shell::mojom::ShellClientRequest client_request) { | |
| 168 // TODO(sky): use MessagePumpMojo. | |
| 169 base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); | |
| 170 shell_client_.reset(new DefaultShellClient); | |
| 171 shell_connection_.reset(new mojo::ShellConnection(shell_client_.get(), | |
| 172 std::move(client_request))); | |
| 173 message_loop.Run(); | |
| 174 } | |
| 175 | |
| 176 int MashMain() { | |
| 177 #if defined(OS_WIN) | |
| 178 base::RouteStdioToConsole(false); | |
| 179 #endif | |
| 180 // TODO(sky): wire this up correctly. | |
| 181 logging::LoggingSettings settings; | |
| 182 settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; | |
| 183 logging::InitLogging(settings); | |
| 184 // To view log output with IDs and timestamps use "adb logcat -v threadtime". | |
| 185 logging::SetLogItems(false, // Process ID | |
| 186 false, // Thread ID | |
| 187 false, // Timestamp | |
| 188 false); // Tick count | |
| 189 | |
| 190 mojo::RegisterMojoSchemes(); | |
| 191 // TODO(sky): use MessagePumpMojo. | |
| 192 scoped_ptr<base::MessageLoop> message_loop; | |
| 193 #if defined(OS_LINUX) | |
| 194 base::AtExitManager exit_manager; | |
| 195 #endif | |
| 196 if (!IsChild()) | |
| 197 message_loop.reset(new base::MessageLoop(base::MessageLoop::TYPE_UI)); | |
| 198 MashRunner mash_runner; | |
| 199 mash_runner.Run(); | |
| 200 return 0; | |
| 201 } | |
| OLD | NEW |