OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 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 "mojo/shell/service_manager.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback_helpers.h" | |
9 #include "base/command_line.h" | |
10 #include "base/file_util.h" | |
11 #include "base/scoped_native_library.h" | |
12 #include "base/threading/simple_thread.h" | |
13 #include "mojo/public/bindings/lib/remote_ptr.h" | |
14 #include "mojo/shell/context.h" | |
15 #include "mojo/shell/switches.h" | |
16 #include "mojom/shell.h" | |
17 | |
18 typedef MojoResult (*MojoMainFunction)(MojoHandle pipe); | |
19 | |
20 namespace mojo { | |
21 namespace shell { | |
22 | |
23 class ServiceManager::Service | |
24 : public ::shell::ShellStub, | |
25 public Loader::Delegate, | |
26 public base::DelegateSimpleThread::Delegate { | |
27 public: | |
28 Service(ServiceManager* manager, const GURL& url) | |
29 : manager_(manager), | |
30 url_(url), | |
31 weak_factory_(this) { | |
32 base::AutoLock lock(lock_); | |
abarth-chromium
2013/12/10 04:53:51
You're still planning to remove this lock, right?
DaveMoore
2013/12/11 18:56:44
Done.
| |
33 ScopedMessagePipeHandle shell_handle; | |
34 CreateMessagePipe(&shell_handle, &service_handle_); | |
35 shell_client_.reset(shell_handle.Pass()); | |
36 shell_client_.SetPeer(this); | |
37 request_ = manager_->context_->loader()->Load(url_, this); | |
38 } | |
39 | |
40 virtual ~Service() {} | |
41 | |
42 void ConnectToClient(ScopedMessagePipeHandle handle) { | |
43 if (handle.is_valid()) | |
44 shell_client_->Connect(handle.Pass()); | |
45 } | |
46 | |
47 virtual void Connect(const mojo::String& url, | |
darin (slow to review)
2013/12/10 06:12:36
nit: no need for the "mojo::" prefix inside the mo
DaveMoore
2013/12/11 18:56:44
Done.
| |
48 ScopedMessagePipeHandle client_pipe) MOJO_OVERRIDE { | |
49 manager_->Connect(GURL(url.To<std::string>()), client_pipe.Pass()); | |
darin (slow to review)
2013/12/10 06:12:36
note: we could write a TypeConverter specializatio
| |
50 } | |
51 | |
52 private: | |
53 // From Loader::Delegate. | |
54 virtual void DidCompleteLoad(const GURL& app_url, | |
55 const base::FilePath& app_path) OVERRIDE { | |
56 base::AutoLock lock(lock_); | |
57 app_path_ = app_path; | |
58 ack_closure_ = | |
59 base::Bind(&Service::AppCompleted, weak_factory_.GetWeakPtr()); | |
60 thread_.reset(new base::DelegateSimpleThread(this, "app_thread")); | |
61 thread_->Start(); | |
62 } | |
63 | |
64 // From base::DelegateSimpleThread::Delegate. | |
65 virtual void Run() OVERRIDE { | |
66 base::ScopedClosureRunner app_deleter( | |
67 base::Bind(base::IgnoreResult(&base::DeleteFile), app_path_, false)); | |
68 base::ScopedNativeLibrary app_library( | |
69 base::LoadNativeLibrary(app_path_, NULL)); | |
70 if (!app_library.is_valid()) { | |
71 LOG(ERROR) << "Failed to load library: " << app_path_.value().c_str(); | |
72 return; | |
73 } | |
74 | |
75 MojoMainFunction main_function = reinterpret_cast<MojoMainFunction>( | |
76 app_library.GetFunctionPointer("MojoMain")); | |
77 if (!main_function) { | |
78 LOG(ERROR) << "Entrypoint MojoMain not found."; | |
79 return; | |
80 } | |
81 | |
82 // |MojoMain()| takes ownership of the app handle. | |
83 MojoResult result = main_function(service_handle_.release().value()); | |
84 if (result < MOJO_RESULT_OK) { | |
85 LOG(ERROR) << "MojoMain returned an error: " << result; | |
86 return; | |
87 } | |
88 manager_->context_->task_runners()->ui_runner()->PostTask( | |
89 FROM_HERE, | |
90 ack_closure_); | |
91 } | |
92 | |
93 void AppCompleted() { | |
94 thread_->Join(); | |
95 thread_.reset(); | |
96 } | |
97 | |
98 base::Lock lock_; | |
99 ServiceManager* manager_; | |
100 GURL url_; | |
101 mojo::RemotePtr<::shell::ShellClient> shell_client_; | |
darin (slow to review)
2013/12/10 06:12:36
nit: ditto re: mojo::
DaveMoore
2013/12/11 18:56:44
Done.
| |
102 base::FilePath app_path_; | |
103 base::Closure ack_closure_; | |
104 scoped_ptr<Loader::Job> request_; | |
105 scoped_ptr<base::DelegateSimpleThread> thread_; | |
106 ScopedMessagePipeHandle service_handle_; | |
107 | |
108 base::WeakPtrFactory<Service> weak_factory_; | |
109 | |
110 DISALLOW_COPY_AND_ASSIGN(Service); | |
111 }; | |
112 | |
113 ServiceManager::ServiceManager(Context* context) : context_(context) { | |
114 } | |
115 | |
116 ServiceManager::~ServiceManager() { | |
117 } | |
118 | |
119 void ServiceManager::Connect(const GURL& url, | |
120 ScopedMessagePipeHandle client_handle) { | |
121 GURL app_url = url; | |
122 if (url.scheme() == "mojo") { | |
123 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
124 std::string origin = command_line.GetSwitchValueASCII(switches::kOrigin); | |
125 std::string lib("lib" + url.ExtractFileName() + ".so"); | |
abarth-chromium
2013/12/10 04:53:51
We still have the problem of this not working on W
Ben Goodger (Google)
2013/12/10 16:35:03
windows impl:
std::string lib(url.ExtractFileName
DaveMoore
2013/12/11 18:56:44
Added windows impl, still need to figure out mac
O
| |
126 app_url = GURL(origin + std::string("/") + lib); | |
127 } | |
128 ServiceMap::const_iterator service_it = url_to_service_.find(app_url); | |
129 Service* service; | |
130 if (service_it != url_to_service_.end()) { | |
131 service = service_it->second; | |
132 } else { | |
133 service = new Service(this, app_url); | |
134 url_to_service_[app_url] = service; | |
135 } | |
136 service->ConnectToClient(client_handle.Pass()); | |
137 } | |
138 | |
139 } // namespace shell | |
140 } // namespace mojo | |
OLD | NEW |