[M85 Dev][EFL] Fix crashes at webview launch
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / ewk_global_data.cc
1 // Copyright 2014 Samsung Electronics. 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 "ewk_global_data.h"
6
7 #include "base/cpu.h"
8 #include "base/logging.h"
9 #include "base/message_loop/message_pump_for_ui_efl.h"
10 #include "base/path_service.h"
11 #include "browser/autofill/personal_data_manager_factory.h"
12 #include "components/discardable_memory/service/discardable_shared_memory_manager.h"
13 #include "content/app/service_manager_environment.h"
14 #include "content/browser/browser_process_sub_thread.h"
15 #include "content/browser/gpu/gpu_main_thread_factory.h"
16 #include "content/browser/gpu/gpu_process_host.h"
17 #include "content/browser/renderer_host/render_process_host_impl.h"
18 #include "content/browser/scheduler/browser_task_executor.h"
19 #include "content/browser/startup_helper.h"
20 #include "content/browser/utility_process_host.h"
21 #include "content/child/field_trial.h"
22 #include "content/gpu/in_process_gpu_thread.h"
23 #include "content/public/app/content_main.h"
24 #include "content/public/app/content_main_runner.h"
25 #include "content/public/browser/browser_main_runner.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/common/content_switches.h"
29 #include "content/renderer/in_process_renderer_thread.h"
30 #include "content/utility/in_process_utility_thread.h"
31 #include "efl/window_factory.h"
32 #include "eweb_view.h"
33 #include "mojo/core/embedder/embedder.h"
34 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/ozone/public/ozone_platform.h"
36
37 #include "command_line_efl.h"
38 #include "content_main_delegate_efl.h"
39 #include "ui/display/screen_efl.h"
40
41 #ifdef OS_TIZEN
42 #include <dlfcn.h>
43 void* EflExtensionHandle = 0;
44 #endif
45
46 using content::BrowserMainRunner;
47 using content::BrowserThread;
48 using content::ContentMainDelegateEfl;
49 using content::ContentMainRunner;
50 using content::GpuProcessHost;
51 using content::RenderProcessHost;
52 using content::UtilityProcessHost;
53
54 EwkGlobalData* EwkGlobalData::instance_ = NULL;
55
56 namespace {
57
58 std::unique_ptr<base::MessagePump> MessagePumpFactory() {
59   return std::unique_ptr<base::MessagePump>(new base::MessagePumpForUIEfl);
60 }
61
62 }  // namespace
63
64 EwkGlobalData::EwkGlobalData()
65     : content_main_runner_(ContentMainRunner::Create()),
66       content_main_delegate_efl_(new ContentMainDelegateEfl) {}
67
68 EwkGlobalData::~EwkGlobalData() {
69   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
70   // URLRequestContextGetterEfl needs to be deleted before loop stops
71   system_request_context_ = nullptr;
72
73 // MessageLoop::QuitNow is deprecated. Should use RunLoop::Quit()
74 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
75   // We need to pretend that message loop was stopped so chromium unwinds
76   // correctly
77   MessageLoop* loop = MessageLoop::current();
78   loop->QuitNow();
79 #endif
80
81 // Since we forcibly shutdown our UI message loop, it is possible
82 // that important pending Tasks are simply not executed.
83 // Among these, the destruction of RenderProcessHostImpl class
84 // (scheduled with DeleteSoon) performs various process umplumbing
85 // stuff and also holds strong references of lots of other objects
86 // (e.g. URLRequestContextGetterEfl, RenderWidgetHelper,
87 // ChildProcessLauncher). Not performing the proper destruction
88 // of them might result in crashes or other undefined problems.
89 //
90 // Line below gives the message loop a extra run ('till it gets idle)
91 // to perform such pending tasks.
92 #if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
93   // FIXME: EWK_BRINGUP definition should be removed.
94   loop->RunUntilIdle();
95 #endif  // !defined(EWK_BRINGUP)
96 }
97
98 EwkGlobalData* EwkGlobalData::GetInstance() {
99   if (instance_) {
100     CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
101     return instance_;
102   }
103
104   // Workaround for cpu info logging asserting if executed on the wrong thread
105   // during cpu info lazy instance initialization.
106   base::CPU cpu;
107   DCHECK(cpu.cpu_brand() != "");
108
109   instance_ = new EwkGlobalData();
110
111   // TODO: Check if service_manager::Main should be used instead.
112   // The Mojo EDK must be initialized before using IPC.
113   mojo::core::Init();
114
115   base::MessagePump::OverrideMessagePumpForUIFactory(&MessagePumpFactory);
116
117   efl::WindowFactory::SetDelegate(&EWebView::GetHostWindowDelegate);
118
119   // Call to CommandLineEfl::GetDefaultPortParams() should be before content
120   // main runner initialization in order to pass command line parameters
121   // for current process that are used in content main runner initialization.
122   content::MainFunctionParams main_funtion_params =
123       CommandLineEfl::GetDefaultPortParams();
124
125   content::ContentMainParams params(
126       instance_->content_main_delegate_efl_.get());
127   params.argc = CommandLineEfl::GetArgc();
128   params.argv = CommandLineEfl::GetArgv();
129   instance_->content_main_runner_->Initialize(params);
130
131   // ScreenEfl should be installed only after CommandLine has been initialized.
132   ui::InstallScreenInstance();
133
134 #if defined(USE_OZONE)
135   ui::OzonePlatform::InitParams init_params;
136   init_params.single_process = true;
137   ui::OzonePlatform::InitializeForUI(init_params);
138 #endif
139
140   content::InitializeFieldTrialAndFeatureList();
141
142   // Start ThreadPool before creating BrowserMainLoop.
143   base::ThreadPoolInstance::Create("Browser");
144   content::StartBrowserThreadPool();
145   content::BrowserTaskExecutor::Create();
146
147   instance_->discardable_shared_memory_manager_ =
148       std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
149
150   instance_->service_manager_environment_ =
151       std::make_unique<content::ServiceManagerEnvironment>(
152           content::BrowserTaskExecutor::CreateIOThread());
153   instance_->startup_data_ =
154       instance_->service_manager_environment_->CreateBrowserStartupData();
155   main_funtion_params.startup_data = instance_->startup_data_.get();
156
157   instance_->browser_main_runner_ = BrowserMainRunner::Create();
158   instance_->browser_main_runner_->Initialize(main_funtion_params);
159
160   base::ThreadRestrictions::SetIOAllowed(true);
161
162   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
163           switches::kSingleProcess)) {
164     content::UtilityProcessHost::RegisterUtilityMainThreadFactory(
165         content::CreateInProcessUtilityThread);
166     content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(
167         content::CreateInProcessRendererThread);
168     content::RegisterGpuMainThreadFactory(
169         reinterpret_cast<content::GpuMainThreadFactoryFunction>(
170             content::CreateInProcessGpuThread));
171   }
172
173 #ifndef NDEBUG
174   logging::LoggingSettings settings;
175   settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
176   logging::InitLogging(settings);
177   logging::SetLogItems(true, true, true, true);
178 #endif
179
180 #ifdef OS_TIZEN
181   if (!EflExtensionHandle)
182     EflExtensionHandle = dlopen("/usr/lib/libefl-extension.so.0", RTLD_LAZY);
183 #endif
184
185   return instance_;
186 }
187
188 content::URLRequestContextGetterEfl*
189 EwkGlobalData::GetSystemRequestContextGetter() {
190   if (!system_request_context_.get()) {
191     system_request_context_ = new content::URLRequestContextGetterEfl();
192   }
193   return system_request_context_.get();
194 }
195
196 void EwkGlobalData::Delete() {
197   delete instance_;
198   instance_ = NULL;
199 }
200
201 // static
202 bool EwkGlobalData::IsInitialized() {
203   return instance_ != NULL;
204 }