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/runner/native_application_support.h"
7 #include "base/command_line.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/logging.h"
11 #include "mojo/platform_handle/platform_handle_private_thunks.h"
12 #include "mojo/public/platform/native/gles2_impl_chromium_extension_thunks.h"
13 #include "mojo/public/platform/native/gles2_impl_thunks.h"
14 #include "mojo/public/platform/native/gles2_thunks.h"
15 #include "mojo/public/platform/native/system_thunks.h"
22 template <typename Thunks
>
23 bool SetThunks(Thunks (*make_thunks
)(),
24 const char* function_name
,
25 base::NativeLibrary library
) {
26 typedef size_t (*SetThunksFn
)(const Thunks
* thunks
);
27 SetThunksFn set_thunks
= reinterpret_cast<SetThunksFn
>(
28 base::GetFunctionPointerFromNativeLibrary(library
, function_name
));
31 Thunks thunks
= make_thunks();
32 size_t expected_size
= set_thunks(&thunks
);
33 if (expected_size
> sizeof(Thunks
)) {
34 LOG(ERROR
) << "Invalid app library: expected " << function_name
35 << " to return thunks of size: " << expected_size
;
43 base::NativeLibrary
LoadNativeApplication(const base::FilePath
& app_path
) {
44 DVLOG(2) << "Loading Mojo app in process from library: " << app_path
.value();
46 base::NativeLibraryLoadError error
;
47 base::NativeLibrary app_library
= base::LoadNativeLibrary(app_path
, &error
);
48 LOG_IF(ERROR
, !app_library
)
49 << "Failed to load app library (error: " << error
.ToString() << ")";
53 bool RunNativeApplication(base::NativeLibrary app_library
,
54 InterfaceRequest
<Application
> application_request
) {
55 // Tolerate |app_library| being null, to make life easier for callers.
59 if (!SetThunks(&MojoMakeSystemThunks
, "MojoSetSystemThunks", app_library
)) {
60 LOG(ERROR
) << "MojoSetSystemThunks not found";
64 if (SetThunks(&MojoMakeGLES2ControlThunks
, "MojoSetGLES2ControlThunks",
66 // If we have the control thunks, we should also have the GLES2
67 // implementation thunks.
68 if (!SetThunks(&MojoMakeGLES2ImplThunks
, "MojoSetGLES2ImplThunks",
71 << "MojoSetGLES2ControlThunks found, but not MojoSetGLES2ImplThunks";
75 // If the application is using GLES2 extension points, register those
76 // thunks. Applications may use or not use any of these, so don't warn if
78 SetThunks(MojoMakeGLES2ImplChromiumExtensionThunks
,
79 "MojoSetGLES2ImplChromiumExtensionThunks", app_library
);
81 // Unlike system thunks, we don't warn on a lack of GLES2 thunks because
82 // not everything is a visual app.
84 // Go shared library support requires us to initialize the runtime before we
85 // start running any go code. This is a temporary patch.
86 typedef void (*InitGoRuntimeFn
)();
87 InitGoRuntimeFn init_go_runtime
= reinterpret_cast<InitGoRuntimeFn
>(
88 base::GetFunctionPointerFromNativeLibrary(app_library
, "InitGoRuntime"));
89 if (init_go_runtime
) {
90 DVLOG(2) << "InitGoRuntime: Initializing Go Runtime found in app";
95 // On Windows, initializing base::CommandLine with null parameters gets the
96 // process's command line from the OS. Other platforms need it to be passed
97 // in. This needs to be passed in before the app initializes the command line,
98 // which is done as soon as it loads.
99 typedef void (*InitCommandLineArgs
)(int, const char* const*);
100 InitCommandLineArgs init_command_line_args
=
101 reinterpret_cast<InitCommandLineArgs
>(
102 base::GetFunctionPointerFromNativeLibrary(app_library
,
103 "InitCommandLineArgs"));
104 if (init_command_line_args
) {
106 base::CommandLine
* cmd_line
= base::CommandLine::ForCurrentProcess();
107 const char** argv
= new const char* [cmd_line
->argv().size()];
108 for (auto& arg
: cmd_line
->argv())
109 argv
[argc
++] = arg
.c_str();
110 init_command_line_args(argc
, argv
);
114 // Apps need not include platform handle thunks.
115 SetThunks(&MojoMakePlatformHandlePrivateThunks
,
116 "MojoSetPlatformHandlePrivateThunks", app_library
);
118 typedef MojoResult (*MojoMainFunction
)(MojoHandle
);
119 MojoMainFunction main_function
= reinterpret_cast<MojoMainFunction
>(
120 base::GetFunctionPointerFromNativeLibrary(app_library
, "MojoMain"));
121 if (!main_function
) {
122 LOG(ERROR
) << "MojoMain not found";
125 // |MojoMain()| takes ownership of the service handle.
126 MojoHandle handle
= application_request
.PassMessagePipe().release().value();
127 MojoResult result
= main_function(handle
);
128 if (result
!= MOJO_RESULT_OK
) {
129 LOG(ERROR
) << "MojoMain returned error (result: " << result
<< ")";
134 } // namespace runner