Upstream version 11.39.256.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / browser / application_tizen.cc
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.
5
6 #include "xwalk/application/browser/application_tizen.h"
7
8 #include <set>
9 #include <string>
10 #include <vector>
11
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"
18
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"
24
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"
31 #endif
32
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"
36
37 namespace xwalk {
38
39 namespace keys = application_manifest_keys;
40 namespace widget_keys = application_widget_keys;
41
42 namespace application {
43
44 const char kDefaultMediaAppClass[] = "player";
45 namespace {
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);
53
54   unsigned int fullscreen_options = runtime->fullscreen_options();
55   if (params->state == ui::SHOW_STATE_FULLSCREEN)
56     fullscreen_options |= Runtime::FULLSCREEN_FOR_LAUNCH;
57   else
58     fullscreen_options &= ~Runtime::FULLSCREEN_FOR_LAUNCH;
59   runtime->set_fullscreen_options(fullscreen_options);
60 }
61
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);
67 }
68 #endif
69 }  // namespace
70
71 blink::WebScreenOrientationLockType GetDefaultOrientation(
72     const base::WeakPtr<Application>& app) {
73   TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
74     app->data()->GetManifestData(widget_keys::kTizenSettingKey));
75   if (!info)
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;
84     default:
85       NOTREACHED();
86       return blink::WebScreenOrientationLockDefault;
87   }
88 }
89
90 class ScreenOrientationProviderTizen :
91     public content::ScreenOrientationProvider {
92  public:
93   ScreenOrientationProviderTizen(
94       const base::WeakPtr<Application>& app,
95       content::ScreenOrientationDispatcherHost* dispatcher)
96       : app_(app),
97         dispatcher_(dispatcher),
98         request_id_(0) {
99     DCHECK(dispatcher_);
100   }
101
102   virtual void LockOrientation(
103       int request_id,
104       blink::WebScreenOrientationLockType lock) OVERRIDE {
105     if (!app_) {
106       dispatcher_->NotifyLockError(
107           request_id,
108           blink::WebLockOrientationError::WebLockOrientationErrorNotAvailable);
109       return;
110     }
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);
120         break;
121       }
122     }
123     dispatcher_->NotifyLockSuccess(request_id);
124   }
125
126   virtual void UnlockOrientation() OVERRIDE {
127     LockOrientation(request_id_, GetDefaultOrientation(app_));
128   }
129
130   virtual void OnOrientationChange() OVERRIDE {}
131
132  private:
133   base::WeakPtr<Application> app_;
134   content::ScreenOrientationDispatcherHost* dispatcher_;
135   int request_id_;
136 };
137
138 ApplicationTizen::ApplicationTizen(
139     scoped_refptr<ApplicationData> data,
140     XWalkBrowserContext* browser_context)
141     : Application(data, browser_context),
142 #if defined(OS_TIZEN_MOBILE)
143       root_window_(NULL),
144 #endif
145       is_suspended_(false) {
146 #if defined(USE_OZONE)
147   ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
148 #endif
149   cookie_manager_ = scoped_ptr<CookieManager>(
150       new CookieManager(id(), browser_context_));
151 }
152
153 ApplicationTizen::~ApplicationTizen() {
154 #if defined(USE_OZONE)
155   ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
156 #endif
157 }
158
159 void ApplicationTizen::Hide() {
160   DCHECK(!runtimes_.empty());
161   for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
162     if ((*it)->window())
163       (*it)->window()->Minimize();
164   }
165 }
166
167 void ApplicationTizen::Show() {
168   DCHECK(!runtimes_.empty());
169   for (Runtime* runtime : runtimes_) {
170     if (auto window = runtime->window())
171       window->Restore();
172   }
173 }
174
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();
183     }
184 #endif
185     DCHECK(web_contents_);
186
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;
193
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);
201
202     content::ScreenOrientationDispatcherHost* host =
203         web_contents_->GetScreenOrientationDispatcherHost();
204     content::ScreenOrientationProvider* provider =
205         new ScreenOrientationProviderTizen(GetWeakPtr(), host);
206     host->SetProvider(provider);
207
208     provider->LockOrientation(0, GetDefaultOrientation(GetWeakPtr()));
209     return true;
210   }
211   return false;
212 }
213
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()));
218   }
219   return base::FilePath();
220 }
221
222 bool ApplicationTizen::CanBeSuspended() const {
223   if (TizenSettingInfo* setting = static_cast<TizenSettingInfo*>(
224           data()->GetManifestData(widget_keys::kTizenSettingKey))) {
225     return !setting->background_support_enabled();
226   }
227   return true;
228 }
229
230 void ApplicationTizen::Suspend() {
231   if (is_suspended_ || !CanBeSuspended())
232     return;
233
234   DCHECK(render_process_host_);
235   render_process_host_->Send(new ViewMsg_SuspendJSEngine(true));
236
237   DCHECK(!runtimes_.empty());
238   for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
239     if ((*it)->web_contents())
240       (*it)->web_contents()->WasHidden();
241   }
242   is_suspended_ = true;
243 }
244
245 void ApplicationTizen::Resume() {
246   if (!is_suspended_ || !CanBeSuspended())
247     return;
248
249   DCHECK(render_process_host_);
250   render_process_host_->Send(new ViewMsg_SuspendJSEngine(false));
251
252   DCHECK(!runtimes_.empty());
253   for (auto it = runtimes_.begin(); it != runtimes_.end(); ++it) {
254     if ((*it)->web_contents())
255       (*it)->web_contents()->WasShown();
256   }
257   is_suspended_ = false;
258 }
259
260 #if defined(USE_OZONE)
261 void ApplicationTizen::WillProcessEvent(const ui::PlatformEvent& event) {}
262
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)
267     return;
268
269   ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(ui_event);
270
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)
278     return;
279
280   TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
281       data()->GetManifestData(widget_keys::kTizenSettingKey));
282   if (info && !info->hwkey_enabled())
283     return;
284
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()));
289   }
290 }
291 #endif
292
293 void ApplicationTizen::RemoveAllCookies() {
294   cookie_manager_->RemoveAllCookies();
295 }
296
297 void ApplicationTizen::SetUserAgentString(
298     const std::string& user_agent_string) {
299   cookie_manager_->SetUserAgentString(render_process_host_, user_agent_string);
300 }
301
302 void ApplicationTizen::OnNewRuntimeAdded(Runtime* runtime) {
303   DCHECK(runtime);
304   Application::OnNewRuntimeAdded(runtime);
305 #if defined(OS_TIZEN_MOBILE)
306   if (root_window_ && runtimes_.size() > 1)
307       root_window_->Show();
308 #endif
309 }
310
311 void ApplicationTizen::OnRuntimeClosed(Runtime* runtime) {
312   DCHECK(runtime);
313   Application::OnRuntimeClosed(runtime);
314 #if defined(OS_TIZEN_MOBILE)
315   if (runtimes_.empty() && root_window_) {
316     root_window_->Close();
317     root_window_ = NULL;
318   }
319 #endif
320 }
321
322 }  // namespace application
323 }  // namespace xwalk