| // Copyright 2017 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/browser/lib/exported/main.h" |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "cobalt/base/wrap_main.h" |
| #include "cobalt/browser/application.h" |
| #include "starboard/event.h" |
| #include "starboard/input.h" |
| |
| namespace { |
| |
| cobalt::browser::Application* g_application = NULL; |
| typedef base::Callback<void(void)> InitializedCallback; |
| typedef base::Callback<bool(const SbEvent*)> HandleEventCallback; |
| static base::LazyInstance<InitializedCallback> |
| g_on_cobalt_initialized_callback = LAZY_INSTANCE_INITIALIZER; |
| static base::LazyInstance<HandleEventCallback> g_handle_event_callback = |
| LAZY_INSTANCE_INITIALIZER; |
| |
| // We cannot use LazyInstance here as this can be set before Cobalt has been |
| // initialized at all - thus there will not yet exist an AtExitManager which |
| // means the app would crash if we tried to replace the lazy instance too |
| // early. Instead, for this one callback, we simply do things manually. |
| CbLibMainCallbackRegistrationReadyCallback g_callback_registration_ready = |
| nullptr; |
| void* g_registration_ready_context = nullptr; |
| |
| void PreloadApplication(int /*argc*/, char** /*argv*/, const char* /*link*/, |
| const base::Closure& quit_closure) { |
| LOG(INFO) << "Preloading application."; |
| DCHECK(!g_application); |
| CHECK(g_callback_registration_ready); |
| // Register a default event handler up front. |
| CbLibMainSetHandleEventCallback(nullptr, nullptr); |
| g_callback_registration_ready(g_registration_ready_context); |
| g_application = |
| new cobalt::browser::Application(quit_closure, true /*should_preload*/); |
| DCHECK(g_application); |
| } |
| |
| void StartApplication(int /*argc*/, char** /*argv*/, const char* /*link*/, |
| const base::Closure& quit_closure) { |
| LOG(INFO) << "Starting application."; |
| if (!g_application) { |
| CHECK(g_callback_registration_ready); |
| // Register a default event handler up front. |
| CbLibMainSetHandleEventCallback(nullptr, nullptr); |
| g_callback_registration_ready(g_registration_ready_context); |
| g_application = new cobalt::browser::Application(quit_closure, |
| false /*should_preload*/); |
| DCHECK(g_application); |
| } else { |
| g_application->Start(); |
| } |
| DCHECK(g_application); |
| if (!g_on_cobalt_initialized_callback.Get().is_null()) |
| g_on_cobalt_initialized_callback.Get().Run(); |
| } |
| |
| void StopApplication() { |
| DCHECK(g_application); |
| LOG(INFO) << "Stopping application."; |
| delete g_application; |
| g_application = NULL; |
| } |
| |
| void HandleStarboardEvent(const SbEvent* starboard_event) { |
| if (!g_application) { |
| return; |
| } |
| |
| // TODO(dworsham): Host-generated input events will also be fed through the |
| // host callback, leading to re-entrancy issues. Set up a way of filtering |
| // them somehow. |
| // |
| // For now, works fine with YTVR as only input events are generated by the |
| // host and the host also ignores all input events sent its way. |
| if (!g_handle_event_callback.Get().Run(starboard_event)) { |
| g_application->HandleStarboardEvent(starboard_event); |
| } |
| } |
| |
| } // namespace |
| |
| COBALT_WRAP_MAIN(PreloadApplication, StartApplication, HandleStarboardEvent, |
| StopApplication); |
| |
| void CbLibMainSetCallbackRegistrationReadyCallback( |
| void* context, CbLibMainOnCobaltInitializedCallback callback) { |
| g_registration_ready_context = context; |
| g_callback_registration_ready = callback; |
| } |
| |
| void CbLibMainSetOnCobaltInitializedCallback( |
| void* context, CbLibMainOnCobaltInitializedCallback callback) { |
| g_on_cobalt_initialized_callback.Get() = |
| callback ? base::Bind(callback, context) : InitializedCallback(); |
| } |
| |
| void CbLibMainSetHandleEventCallback(void* context, |
| CbLibMainHandleEventCallback callback) { |
| // If the user passes nullptr, provide a default event handler so that it is |
| // never actually null. |
| g_handle_event_callback.Get() = callback ? |
| base::Bind(callback, context) : |
| base::Bind([](const SbEvent*) { |
| return false; |
| }); |
| } |
| |
| SbWindow CbLibMainGetSbWindow() { |
| auto* primary_window = cobalt::system_window::SystemWindow::PrimaryWindow(); |
| return primary_window ? primary_window->GetSbWindow() : nullptr; |
| } |