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_copy_texture_thunks.h"
13 #include "mojo/public/platform/native/gles2_impl_chromium_image_thunks.h"
14 #include "mojo/public/platform/native/gles2_impl_chromium_miscellaneous_thunks.h"
15 #include "mojo/public/platform/native/gles2_impl_chromium_pixel_transfer_buffer_object_thunks.h"
16 #include "mojo/public/platform/native/gles2_impl_chromium_sub_image_thunks.h"
17 #include "mojo/public/platform/native/gles2_impl_chromium_sync_point_thunks.h"
18 #include "mojo/public/platform/native/gles2_impl_chromium_texture_mailbox_thunks.h"
19 #include "mojo/public/platform/native/gles2_impl_occlusion_query_ext_thunks.h"
20 #include "mojo/public/platform/native/gles2_impl_thunks.h"
21 #include "mojo/public/platform/native/gles2_thunks.h"
22 #include "mojo/public/platform/native/system_thunks.h"
29 template <typename Thunks
>
30 bool SetThunks(Thunks (*make_thunks
)(),
31 const char* function_name
,
32 base::NativeLibrary library
) {
33 typedef size_t (*SetThunksFn
)(const Thunks
* thunks
);
34 SetThunksFn set_thunks
= reinterpret_cast<SetThunksFn
>(
35 base::GetFunctionPointerFromNativeLibrary(library
, function_name
));
38 Thunks thunks
= make_thunks();
39 size_t expected_size
= set_thunks(&thunks
);
40 if (expected_size
> sizeof(Thunks
)) {
41 LOG(ERROR
) << "Invalid app library: expected " << function_name
42 << " to return thunks of size: " << expected_size
;
50 base::NativeLibrary
LoadNativeApplication(
51 const base::FilePath
& app_path
,
52 shell::NativeApplicationCleanup cleanup
) {
53 DVLOG(2) << "Loading Mojo app in process from library: " << app_path
.value();
55 base::NativeLibraryLoadError error
;
56 base::NativeLibrary app_library
= base::LoadNativeLibrary(app_path
, &error
);
57 if (cleanup
== shell::NativeApplicationCleanup::DELETE
)
58 DeleteFile(app_path
, false);
59 LOG_IF(ERROR
, !app_library
)
60 << "Failed to load app library (error: " << error
.ToString() << ")";
64 bool RunNativeApplication(base::NativeLibrary app_library
,
65 InterfaceRequest
<Application
> application_request
) {
66 // Tolerate |app_library| being null, to make life easier for callers.
70 if (!SetThunks(&MojoMakeSystemThunks
, "MojoSetSystemThunks", app_library
)) {
71 LOG(ERROR
) << "MojoSetSystemThunks not found";
75 if (SetThunks(&MojoMakeGLES2ControlThunks
, "MojoSetGLES2ControlThunks",
77 // If we have the control thunks, we should also have the GLES2
78 // implementation thunks.
79 if (!SetThunks(&MojoMakeGLES2ImplThunks
, "MojoSetGLES2ImplThunks",
82 << "MojoSetGLES2ControlThunks found, but not MojoSetGLES2ImplThunks";
86 // If the application is using GLES2 extension points, register those
87 // thunks. Applications may use or not use any of these, so don't warn if
89 SetThunks(MojoMakeGLES2ImplChromiumCopyTextureThunks
,
90 "MojoSetGLES2ImplChromiumCopyTextureThunks", app_library
);
91 SetThunks(MojoMakeGLES2ImplChromiumImageThunks
,
92 "MojoSetGLES2ImplChromiumImageThunks", app_library
);
93 SetThunks(MojoMakeGLES2ImplChromiumMiscellaneousThunks
,
94 "MojoSetGLES2ImplChromiumMiscellaneousThunks", app_library
);
95 SetThunks(MojoMakeGLES2ImplChromiumPixelTransferBufferObjectThunks
,
96 "MojoSetGLES2ImplChromiumPixelTransferBufferObjectThunks", app_library
);
97 SetThunks(MojoMakeGLES2ImplChromiumSubImageThunks
,
98 "MojoSetGLES2ImplChromiumSubImageThunks", app_library
);
99 SetThunks(MojoMakeGLES2ImplChromiumTextureMailboxThunks
,
100 "MojoSetGLES2ImplChromiumTextureMailboxThunks", app_library
);
101 SetThunks(MojoMakeGLES2ImplChromiumSyncPointThunks
,
102 "MojoSetGLES2ImplChromiumSyncPointThunks", app_library
);
103 SetThunks(MojoMakeGLES2ImplOcclusionQueryExtThunks
,
104 "MojoSetGLES2ImplOcclusionQueryExtThunks", app_library
);
106 // Unlike system thunks, we don't warn on a lack of GLES2 thunks because
107 // not everything is a visual app.
109 // Go shared library support requires us to initialize the runtime before we
110 // start running any go code. This is a temporary patch.
111 typedef void (*InitGoRuntimeFn
)();
112 InitGoRuntimeFn init_go_runtime
= reinterpret_cast<InitGoRuntimeFn
>(
113 base::GetFunctionPointerFromNativeLibrary(app_library
, "InitGoRuntime"));
114 if (init_go_runtime
) {
115 DVLOG(2) << "InitGoRuntime: Initializing Go Runtime found in app";
120 // On Windows, initializing base::CommandLine with null parameters gets the
121 // process's command line from the OS. Other platforms need it to be passed
122 // in. This needs to be passed in before the app initializes the command line,
123 // which is done as soon as it loads.
124 typedef void (*InitCommandLineArgs
)(int, const char* const*);
125 InitCommandLineArgs init_command_line_args
=
126 reinterpret_cast<InitCommandLineArgs
>(
127 base::GetFunctionPointerFromNativeLibrary(app_library
,
128 "InitCommandLineArgs"));
129 if (init_command_line_args
) {
131 base::CommandLine
* cmd_line
= base::CommandLine::ForCurrentProcess();
132 const char** argv
= new const char* [cmd_line
->argv().size()];
133 for (auto& arg
: cmd_line
->argv())
134 argv
[argc
++] = arg
.c_str();
135 init_command_line_args(argc
, argv
);
139 // Apps need not include platform handle thunks.
140 SetThunks(&MojoMakePlatformHandlePrivateThunks
,
141 "MojoSetPlatformHandlePrivateThunks", app_library
);
143 typedef MojoResult (*MojoMainFunction
)(MojoHandle
);
144 MojoMainFunction main_function
= reinterpret_cast<MojoMainFunction
>(
145 base::GetFunctionPointerFromNativeLibrary(app_library
, "MojoMain"));
146 if (!main_function
) {
147 LOG(ERROR
) << "MojoMain not found";
150 // |MojoMain()| takes ownership of the service handle.
151 MojoHandle handle
= application_request
.PassMessagePipe().release().value();
152 MojoResult result
= main_function(handle
);
153 if (result
!= MOJO_RESULT_OK
) {
154 LOG(ERROR
) << "MojoMain returned error (result: " << result
<< ")";
159 } // namespace runner