1 // Copyright 2014 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.
5 #include "mojo/shell/in_process_dynamic_service_runner.h"
8 #include "base/callback_helpers.h"
9 #include "base/file_util.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/scoped_native_library.h"
14 #include "mojo/public/platform/native/system_thunks.h"
19 InProcessDynamicServiceRunner::InProcessDynamicServiceRunner(
21 : thread_(this, "app_thread") {
24 InProcessDynamicServiceRunner::~InProcessDynamicServiceRunner() {
25 if (thread_
.HasBeenStarted()) {
26 DCHECK(!thread_
.HasBeenJoined());
31 void InProcessDynamicServiceRunner::Start(
32 const base::FilePath
& app_path
,
33 ScopedShellHandle service_handle
,
34 const base::Closure
& app_completed_callback
) {
37 DCHECK(!service_handle_
.is_valid());
38 service_handle_
= service_handle
.Pass();
40 DCHECK(app_completed_callback_runner_
.is_null());
41 app_completed_callback_runner_
= base::Bind(&base::TaskRunner::PostTask
,
42 base::MessageLoopProxy::current(),
44 app_completed_callback
);
46 DCHECK(!thread_
.HasBeenStarted());
50 void InProcessDynamicServiceRunner::Run() {
51 DVLOG(2) << "Loading/running Mojo app from " << app_path_
.value()
54 base::ScopedClosureRunner
app_deleter(
55 base::Bind(base::IgnoreResult(&base::DeleteFile
), app_path_
, false));
58 base::NativeLibraryLoadError error
;
59 base::ScopedNativeLibrary
app_library(
60 base::LoadNativeLibrary(app_path_
, &error
));
61 if (!app_library
.is_valid()) {
62 LOG(ERROR
) << "Failed to load library (error: " << error
.ToString()
67 MojoSetSystemThunksFn mojo_set_system_thunks_fn
=
68 reinterpret_cast<MojoSetSystemThunksFn
>(app_library
.GetFunctionPointer(
69 "MojoSetSystemThunks"));
70 if (mojo_set_system_thunks_fn
) {
71 MojoSystemThunks system_thunks
= MojoMakeSystemThunks();
72 size_t expected_size
= mojo_set_system_thunks_fn(&system_thunks
);
73 if (expected_size
> sizeof(MojoSystemThunks
)) {
75 << "Invalid DSO. Expected MojoSystemThunks size: "
81 typedef MojoResult (*MojoMainFunction
)(MojoHandle
);
82 MojoMainFunction main_function
= reinterpret_cast<MojoMainFunction
>(
83 app_library
.GetFunctionPointer("MojoMain"));
85 LOG(ERROR
) << "Entrypoint MojoMain not found";
89 // |MojoMain()| takes ownership of the service handle.
90 MojoResult result
= main_function(service_handle_
.release().value());
91 if (result
< MOJO_RESULT_OK
)
92 LOG(ERROR
) << "MojoMain returned an error: " << result
;
95 bool success
= app_completed_callback_runner_
.Run();
96 app_completed_callback_runner_
.Reset();
97 LOG_IF(ERROR
, !success
) << "Failed post run app_completed_callback";