1b59dbe2637ce47138114632b7e8a76c986e36bd
[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/runtime_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   explicit ScreenOrientationProviderTizen(const base::WeakPtr<Application>& app)
94       : app_(app),
95         request_id_(0) {
96   }
97
98   virtual void LockOrientation(
99       int request_id,
100       blink::WebScreenOrientationLockType lock) OVERRIDE {
101     if (!app_)
102       return;
103     request_id_ = request_id;
104     const std::set<Runtime*>& runtimes = app_->runtimes();
105     DCHECK(!runtimes.empty());
106     // FIXME: Probably need better alignment with
107     // https://w3c.github.io/screen-orientation/#screen-orientation-lock-lifetime
108     std::set<Runtime*>::iterator it = runtimes.begin();
109     for (; it != runtimes.end(); ++it) {
110       NativeAppWindow* window = (*it)->window();
111       if (window && window->IsActive()) {
112         ToNativeAppWindowTizen(window)->LockOrientation(lock);
113         break;
114       }
115     }
116   }
117
118   virtual void UnlockOrientation() OVERRIDE {
119     LockOrientation(request_id_, GetDefaultOrientation(app_));
120   }
121
122   virtual void OnOrientationChange() OVERRIDE {}
123
124  private:
125   base::WeakPtr<Application> app_;
126   int request_id_;
127 };
128
129 ApplicationTizen::ApplicationTizen(
130     scoped_refptr<ApplicationData> data,
131     RuntimeContext* runtime_context)
132     : Application(data, runtime_context),
133 #if defined(OS_TIZEN_MOBILE)
134       root_window_(NULL),
135 #endif
136       is_suspended_(false) {
137 #if defined(USE_OZONE)
138   ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
139 #endif
140   cookie_manager_ = scoped_ptr<CookieManager>(
141       new CookieManager(id(), runtime_context_));
142 }
143
144 ApplicationTizen::~ApplicationTizen() {
145 #if defined(USE_OZONE)
146   ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
147 #endif
148 }
149
150 void ApplicationTizen::Hide() {
151   DCHECK(!runtimes_.empty());
152   std::set<Runtime*>::iterator it = runtimes_.begin();
153   for (; it != runtimes_.end(); ++it) {
154     if ((*it)->window())
155       (*it)->window()->Minimize();
156   }
157 }
158
159 void ApplicationTizen::Show() {
160   DCHECK(!runtimes_.empty());
161   for (Runtime* runtime : runtimes_) {
162     if (auto window = runtime->window())
163       window->Restore();
164   }
165 }
166
167 bool ApplicationTizen::Launch(const LaunchParams& launch_params) {
168   if (Application::Launch(launch_params)) {
169 #if defined(OS_TIZEN_MOBILE)
170     if (!runtimes_.empty()) {
171       root_window_ = CreateRootWindow(*(runtimes_.begin()),
172                                       window_show_params_);
173       window_show_params_.parent = root_window_->GetNativeWindow();
174       root_window_->Show();
175     }
176 #endif
177     DCHECK(web_contents_);
178
179     // Get media class of application.
180     const Manifest* manifest = data_->GetManifest();
181     std::string app_class;
182     manifest->GetString(keys::kXWalkMediaAppClass, &app_class);
183     if (app_class.empty())
184       app_class = kDefaultMediaAppClass;
185
186     // Set an application ID and class, which are needed to tag audio
187     // streams in pulseaudio/Murphy.
188     scoped_refptr<content::AudioRendererHost> audio_host =
189         static_cast<content::RenderProcessHostImpl*>(render_process_host_)
190             ->audio_renderer_host();
191     if (audio_host.get())
192       audio_host->SetMediaStreamProperties(id(), app_class);
193
194     content::ScreenOrientationProvider *provider =
195         new ScreenOrientationProviderTizen(GetWeakPtr());
196     web_contents_->GetScreenOrientationDispatcherHost()->SetProvider(provider);
197
198     provider->LockOrientation(0, GetDefaultOrientation(GetWeakPtr()));
199     return true;
200   }
201   return false;
202 }
203
204 base::FilePath ApplicationTizen::GetSplashScreenPath() {
205   if (TizenSplashScreenInfo* ss_info = static_cast<TizenSplashScreenInfo*>(
206       data()->GetManifestData(widget_keys::kTizenSplashScreenKey))) {
207     return data()->path().Append(FILE_PATH_LITERAL(ss_info->src()));
208   }
209   return base::FilePath();
210 }
211
212 void ApplicationTizen::Suspend() {
213   if (is_suspended_)
214     return;
215
216   DCHECK(render_process_host_);
217   render_process_host_->Send(new ViewMsg_SuspendJSEngine(true));
218
219   DCHECK(!runtimes_.empty());
220   std::set<Runtime*>::iterator it = runtimes_.begin();
221   for (; it != runtimes_.end(); ++it) {
222     if ((*it)->web_contents())
223       (*it)->web_contents()->WasHidden();
224   }
225   is_suspended_ = true;
226 }
227
228 void ApplicationTizen::Resume() {
229   if (!is_suspended_)
230     return;
231
232   DCHECK(render_process_host_);
233   render_process_host_->Send(new ViewMsg_SuspendJSEngine(false));
234
235   DCHECK(!runtimes_.empty());
236   std::set<Runtime*>::iterator it = runtimes_.begin();
237   for (; it != runtimes_.end(); ++it) {
238     if ((*it)->web_contents())
239       (*it)->web_contents()->WasShown();
240   }
241   is_suspended_ = false;
242 }
243
244 #if defined(USE_OZONE)
245 void ApplicationTizen::WillProcessEvent(const ui::PlatformEvent& event) {}
246
247 void ApplicationTizen::DidProcessEvent(
248     const ui::PlatformEvent& event) {
249   ui::Event* ui_event = static_cast<ui::Event*>(event);
250   if (!ui_event->IsKeyEvent() || ui_event->type() != ui::ET_KEY_PRESSED)
251     return;
252
253   ui::KeyEvent* key_event = static_cast<ui::KeyEvent*>(ui_event);
254
255   // FIXME: Most Wayland devices don't have similar hardware button for 'back'
256   // and 'memu' as Tizen Mobile, even that hardare buttons could be different
257   // across different kinds of Wayland platforms.
258   // Here use external keyboard button 'Backspace' & 'HOME' to emulate 'back'
259   // and 'menu' key. Should change this if there is customized key binding.
260   if (key_event->key_code() != ui::VKEY_BACK &&
261       key_event->key_code() != ui::VKEY_HOME)
262     return;
263
264   TizenSettingInfo* info = static_cast<TizenSettingInfo*>(
265       data()->GetManifestData(widget_keys::kTizenSettingKey));
266   if (info && !info->hwkey_enabled())
267     return;
268
269   for (std::set<xwalk::Runtime*>::iterator it = runtimes_.begin();
270       it != runtimes_.end(); ++it) {
271     (*it)->web_contents()->GetRenderViewHost()->Send(new ViewMsg_HWKeyPressed(
272         (*it)->web_contents()->GetRoutingID(), key_event->key_code()));
273   }
274 }
275 #endif
276
277 void ApplicationTizen::RemoveAllCookies() {
278   cookie_manager_->RemoveAllCookies();
279 }
280
281 void ApplicationTizen::SetUserAgentString(
282     const std::string& user_agent_string) {
283   cookie_manager_->SetUserAgentString(render_process_host_, user_agent_string);
284 }
285
286 void ApplicationTizen::OnRuntimeAdded(Runtime* runtime) {
287   DCHECK(runtime);
288   Application::OnRuntimeAdded(runtime);
289 #if defined(OS_TIZEN_MOBILE)
290   if (root_window_ && runtimes_.size() > 1)
291       root_window_->Show();
292 #endif
293 }
294
295 void ApplicationTizen::OnRuntimeRemoved(Runtime* runtime) {
296   DCHECK(runtime);
297   Application::OnRuntimeRemoved(runtime);
298 #if defined(OS_TIZEN_MOBILE)
299   if (runtimes_.empty() && root_window_) {
300     root_window_->Close();
301     root_window_ = NULL;
302   }
303 #endif
304 }
305
306 }  // namespace application
307 }  // namespace xwalk