1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 #include "xwalk/application/browser/application_tizen.h"
12 #include "content/browser/renderer_host/media/audio_renderer_host.h"
13 #include "content/browser/renderer_host/render_process_host_impl.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/screen_orientation_dispatcher_host.h"
17 #include "content/public/browser/screen_orientation_provider.h"
19 #include "xwalk/runtime/browser/xwalk_browser_context.h"
20 #include "xwalk/runtime/browser/runtime_url_request_context_getter.h"
21 #include "xwalk/runtime/browser/ui/native_app_window.h"
22 #include "xwalk/runtime/browser/ui/native_app_window_tizen.h"
23 #include "xwalk/runtime/common/xwalk_common_messages.h"
25 #if defined(USE_OZONE)
26 #include "content/public/browser/render_view_host.h"
27 #include "ui/events/event.h"
28 #include "ui/events/event_constants.h"
29 #include "ui/events/keycodes/keyboard_codes_posix.h"
30 #include "ui/events/platform/platform_event_source.h"
33 #include "xwalk/application/common/application_manifest_constants.h"
34 #include "xwalk/application/common/manifest_handlers/tizen_setting_handler.h"
35 #include "xwalk/application/common/manifest_handlers/tizen_splash_screen_handler.h"
39 namespace keys = application_manifest_keys;
40 namespace widget_keys = application_widget_keys;
42 namespace application {
44 const char kDefaultMediaAppClass[] = "player";
46 #if defined(OS_TIZEN_MOBILE)
47 void ApplyRootWindowParams(Runtime* runtime,
48 NativeAppWindow::CreateParams* params) {
49 if (!params->delegate)
50 params->delegate = runtime;
51 if (params->bounds.IsEmpty())
52 params->bounds = gfx::Rect(0, 0, 840, 600);
54 unsigned int fullscreen_options = runtime->fullscreen_options();
55 if (params->state == ui::SHOW_STATE_FULLSCREEN)
56 fullscreen_options |= Runtime::FULLSCREEN_FOR_LAUNCH;
58 fullscreen_options &= ~Runtime::FULLSCREEN_FOR_LAUNCH;
59 runtime->set_fullscreen_options(fullscreen_options);
62 NativeAppWindow* CreateRootWindow(Runtime* runtime,
63 const NativeAppWindow::CreateParams& params) {
64 NativeAppWindow::CreateParams effective_params(params);
65 ApplyRootWindowParams(runtime, &effective_params);
66 return NativeAppWindow::Create(effective_params);
71 blink::WebScreenOrientationLockType GetDefaultOrientation(
72 const base::WeakPtr<Application>& app) {
73 TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
74 app->data()->GetManifestData(widget_keys::kTizenSettingKey));
76 return blink::WebScreenOrientationLockDefault;
77 switch (info->screen_orientation()) {
78 case TizenSettingInfo::PORTRAIT:
79 return blink::WebScreenOrientationLockPortrait;
80 case TizenSettingInfo::LANDSCAPE:
81 return blink::WebScreenOrientationLockLandscape;
82 case TizenSettingInfo::AUTO:
83 return blink::WebScreenOrientationLockAny;
86 return blink::WebScreenOrientationLockDefault;
90 class ScreenOrientationProviderTizen :
91 public content::ScreenOrientationProvider {
93 ScreenOrientationProviderTizen(
94 const base::WeakPtr<Application>& app,
95 content::ScreenOrientationDispatcherHost* dispatcher)
97 dispatcher_(dispatcher),
102 virtual void LockOrientation(
104 blink::WebScreenOrientationLockType lock) OVERRIDE {
106 dispatcher_->NotifyLockError(
108 blink::WebLockOrientationError::WebLockOrientationErrorNotAvailable);
111 request_id_ = request_id;
112 const std::vector<Runtime*>& runtimes = app_->runtimes();
113 DCHECK(!runtimes.empty());
114 // FIXME: Probably need better alignment with
115 // https://w3c.github.io/screen-orientation/#screen-orientation-lock-lifetime
116 for (auto it = runtimes.begin(); it != runtimes.end(); ++it) {
117 NativeAppWindow* window = (*it)->window();
118 if (window && window->IsActive()) {
119 ToNativeAppWindowTizen(window)->LockOrientation(lock);
123 dispatcher_->NotifyLockSuccess(request_id);
126 virtual void UnlockOrientation() OVERRIDE {
127 LockOrientation(request_id_, GetDefaultOrientation(app_));
130 virtual void OnOrientationChange() OVERRIDE {}
133 base::WeakPtr<Application> app_;
134 content::ScreenOrientationDispatcherHost* dispatcher_;
138 ApplicationTizen::ApplicationTizen(
139 scoped_refptr<ApplicationData> data,
140 XWalkBrowserContext* browser_context)
141 : Application(data, browser_context),
142 #if defined(OS_TIZEN_MOBILE)
145 is_suspended_(false) {
146 #if defined(USE_OZONE)
147 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
149 cookie_manager_ = scoped_ptr<CookieManager>(
150 new CookieManager(id(), browser_context_));
153 ApplicationTizen::~ApplicationTizen() {
154 #if defined(USE_OZONE)
155 ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
159 void ApplicationTizen::Hide() {
160 DCHECK(!runtimes_.empty());
161 for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
163 (*it)->window()->Minimize();
167 void ApplicationTizen::Show() {
168 DCHECK(!runtimes_.empty());
169 for (Runtime* runtime : runtimes_) {
170 if (auto window = runtime->window())
175 bool ApplicationTizen::Launch(const LaunchParams& launch_params) {
176 if (Application::Launch(launch_params)) {
177 #if defined(OS_TIZEN_MOBILE)
178 if (!runtimes_.empty()) {
179 root_window_ = CreateRootWindow(*(runtimes_.begin()),
180 window_show_params_);
181 window_show_params_.parent = root_window_->GetNativeWindow();
182 root_window_->Show();
185 DCHECK(web_contents_);
187 // Get media class of application.
188 const Manifest* manifest = data_->GetManifest();
189 std::string app_class;
190 manifest->GetString(keys::kXWalkMediaAppClass, &app_class);
191 if (app_class.empty())
192 app_class = kDefaultMediaAppClass;
194 // Set an application ID and class, which are needed to tag audio
195 // streams in pulseaudio/Murphy.
196 scoped_refptr<content::AudioRendererHost> audio_host =
197 static_cast<content::RenderProcessHostImpl*>(render_process_host_)
198 ->audio_renderer_host();
199 if (audio_host.get())
200 audio_host->SetMediaStreamProperties(id(), app_class);
202 content::ScreenOrientationDispatcherHost* host =
203 web_contents_->GetScreenOrientationDispatcherHost();
204 content::ScreenOrientationProvider* provider =
205 new ScreenOrientationProviderTizen(GetWeakPtr(), host);
206 host->SetProvider(provider);
208 provider->LockOrientation(0, GetDefaultOrientation(GetWeakPtr()));
214 base::FilePath ApplicationTizen::GetSplashScreenPath() {
215 if (TizenSplashScreenInfo* ss_info = static_cast<TizenSplashScreenInfo*>(
216 data()->GetManifestData(widget_keys::kTizenSplashScreenKey))) {
217 return data()->path().Append(FILE_PATH_LITERAL(ss_info->src()));
219 return base::FilePath();
222 bool ApplicationTizen::CanBeSuspended() const {
223 if (TizenSettingInfo* setting = static_cast<TizenSettingInfo*>(
224 data()->GetManifestData(widget_keys::kTizenSettingKey))) {
225 return !setting->background_support_enabled();
230 void ApplicationTizen::Suspend() {
231 if (is_suspended_ || !CanBeSuspended())
234 DCHECK(render_process_host_);
235 render_process_host_->Send(new ViewMsg_SuspendJSEngine(true));
237 DCHECK(!runtimes_.empty());
238 for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
239 if ((*it)->web_contents())
240 (*it)->web_contents()->WasHidden();
242 is_suspended_ = true;
245 void ApplicationTizen::Resume() {
246 if (!is_suspended_ || !CanBeSuspended())
249 DCHECK(render_process_host_);
250 render_process_host_->Send(new ViewMsg_SuspendJSEngine(false));
252 DCHECK(!runtimes_.empty());
253 for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
254 if ((*it)->web_contents())
255 (*it)->web_contents()->WasShown();
257 is_suspended_ = false;
260 #if defined(USE_OZONE)
261 void ApplicationTizen::WillProcessEvent(const ui::PlatformEvent& event) {}
263 void ApplicationTizen::DidProcessEvent(
264 const ui::PlatformEvent& event) {
265 ui::Event* ui_event = static_cast<ui::Event*>(event);
266 if (!ui_event->IsKeyEvent() || ui_event->type() != ui::ET_KEY_PRESSED)
269 ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(ui_event);
271 // FIXME: Most Wayland devices don't have similar hardware button for 'back'
272 // and 'memu' as Tizen Mobile, even that hardare buttons could be different
273 // across different kinds of Wayland platforms.
274 // Here use external keyboard button 'Backspace' & 'HOME' to emulate 'back'
275 // and 'menu' key. Should change this if there is customized key binding.
276 if (key_event->key_code() != ui::VKEY_BACK &&
277 key_event->key_code() != ui::VKEY_HOME)
280 TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
281 data()->GetManifestData(widget_keys::kTizenSettingKey));
282 if (info && !info->hwkey_enabled())
285 for (auto it = runtimes_.begin();
286 it != runtimes_.end(); ++it) {
287 (*it)->web_contents()->GetRenderViewHost()->Send(new ViewMsg_HWKeyPressed(
288 (*it)->web_contents()->GetRoutingID(), key_event->key_code()));
293 void ApplicationTizen::RemoveAllCookies() {
294 cookie_manager_->RemoveAllCookies();
297 void ApplicationTizen::SetUserAgentString(
298 const std::string& user_agent_string) {
299 cookie_manager_->SetUserAgentString(render_process_host_, user_agent_string);
302 void ApplicationTizen::OnNewRuntimeAdded(Runtime* runtime) {
304 Application::OnNewRuntimeAdded(runtime);
305 #if defined(OS_TIZEN_MOBILE)
306 if (root_window_ && runtimes_.size() > 1)
307 root_window_->Show();
311 void ApplicationTizen::OnRuntimeClosed(Runtime* runtime) {
313 Application::OnRuntimeClosed(runtime);
314 #if defined(OS_TIZEN_MOBILE)
315 if (runtimes_.empty() && root_window_) {
316 root_window_->Close();
322 } // namespace application