Upstream version 5.34.97.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / runtime.cc
1 // Copyright (c) 2013 Intel Corporation. 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 "xwalk/runtime/browser/runtime.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/command_line.h"
11 #include "base/message_loop/message_loop.h"
12 #include "xwalk/runtime/browser/image_util.h"
13 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
14 #include "xwalk/runtime/browser/runtime_context.h"
15 #include "xwalk/runtime/browser/runtime_file_select_helper.h"
16 #include "xwalk/runtime/browser/ui/color_chooser.h"
17 #include "xwalk/runtime/browser/xwalk_runner.h"
18 #include "xwalk/runtime/common/xwalk_notification_types.h"
19 #include "xwalk/runtime/common/xwalk_switches.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/notification_source.h"
24 #include "content/public/browser/notification_types.h"
25 #include "content/public/browser/render_view_host.h"
26 #include "content/public/browser/web_contents_view.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "grit/xwalk_resources.h"
29 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/gfx/image/image_skia.h"
31 #include "ui/gfx/native_widget_types.h"
32
33 using content::FaviconURL;
34 using content::WebContents;
35
36 namespace xwalk {
37
38 namespace {
39
40 // The default size for web content area size.
41 const int kDefaultWidth = 840;
42 const int kDefaultHeight = 600;
43
44 }  // namespace
45
46 // static
47 Runtime* Runtime::CreateWithDefaultWindow(
48     RuntimeContext* runtime_context, const GURL& url, Observer* observer) {
49   Runtime* runtime = Runtime::Create(runtime_context, observer);
50   runtime->LoadURL(url);
51   runtime->AttachDefaultWindow();
52   return runtime;
53 }
54
55 // static
56 Runtime* Runtime::Create(
57     RuntimeContext* runtime_context, Observer* observer) {
58   WebContents::CreateParams params(runtime_context, NULL);
59   params.routing_id = MSG_ROUTING_NONE;
60   WebContents* web_contents = WebContents::Create(params);
61
62   Runtime* runtime = new Runtime(web_contents, observer);
63 #if defined(OS_TIZEN)
64   runtime->InitRootWindow();
65 #endif
66
67   return runtime;
68 }
69
70 Runtime::Runtime(content::WebContents* web_contents, Observer* observer)
71     : WebContentsObserver(web_contents),
72       web_contents_(web_contents),
73       window_(NULL),
74       weak_ptr_factory_(this),
75       fullscreen_options_(NO_FULLSCREEN),
76       observer_(observer) {
77   web_contents_->SetDelegate(this);
78   runtime_context_ = RuntimeContext::FromWebContents(web_contents);
79   content::NotificationService::current()->Notify(
80        xwalk::NOTIFICATION_RUNTIME_OPENED,
81        content::Source<Runtime>(this),
82        content::NotificationService::NoDetails());
83 #if defined(OS_TIZEN)
84   root_window_ = NULL;
85 #endif
86   if (observer_)
87     observer_->OnRuntimeAdded(this);
88 }
89
90 Runtime::~Runtime() {
91   content::NotificationService::current()->Notify(
92           xwalk::NOTIFICATION_RUNTIME_CLOSED,
93           content::Source<Runtime>(this),
94           content::NotificationService::NoDetails());
95   if (observer_)
96     observer_->OnRuntimeRemoved(this);
97 }
98
99 void Runtime::AttachDefaultWindow() {
100   NativeAppWindow::CreateParams params;
101   AttachWindow(params);
102 }
103
104 void Runtime::AttachWindow(const NativeAppWindow::CreateParams& params) {
105 #if defined(OS_ANDROID)
106   NOTIMPLEMENTED();
107 #else
108   CHECK(!window_);
109   NativeAppWindow::CreateParams effective_params(params);
110   ApplyWindowDefaultParams(&effective_params);
111
112   // Set the app icon if it is passed from command line.
113   CommandLine* command_line = CommandLine::ForCurrentProcess();
114   if (command_line->HasSwitch(switches::kAppIcon)) {
115     base::FilePath icon_file =
116         command_line->GetSwitchValuePath(switches::kAppIcon);
117     app_icon_ = xwalk_utils::LoadImageFromFilePath(icon_file);
118   } else {
119     // Otherwise, use the default icon for Crosswalk app.
120     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
121     app_icon_ = rb.GetNativeImageNamed(IDR_XWALK_ICON_48);
122   }
123
124   registrar_.Add(this,
125         content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
126         content::Source<content::WebContents>(web_contents_.get()));
127
128   window_ = NativeAppWindow::Create(effective_params);
129   if (!app_icon_.IsEmpty())
130     window_->UpdateIcon(app_icon_);
131   window_->Show();
132 #if defined(OS_TIZEN)
133   if (root_window_)
134     root_window_->Show();
135 #endif
136 #endif
137 }
138
139 void Runtime::LoadURL(const GURL& url) {
140   content::NavigationController::LoadURLParams params(url);
141   params.transition_type = content::PageTransitionFromInt(
142       content::PAGE_TRANSITION_TYPED |
143       content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
144   web_contents_->GetController().LoadURLWithParams(params);
145   web_contents_->GetView()->Focus();
146 }
147
148 void Runtime::Close() {
149   if (window_) {
150     window_->Close();
151     return;
152   }
153   // Runtime should not free itself on Close but be owned
154   // by Application.
155   delete this;
156 }
157
158 NativeAppWindow* Runtime::window() const {
159   return window_;
160 }
161
162 //////////////////////////////////////////////////////
163 // content::WebContentsDelegate:
164 //////////////////////////////////////////////////////
165 content::WebContents* Runtime::OpenURLFromTab(
166     content::WebContents* source, const content::OpenURLParams& params) {
167   // The only one disposition we would take into consideration.
168   DCHECK(params.disposition == CURRENT_TAB);
169   source->GetController().LoadURL(
170       params.url, params.referrer, params.transition, std::string());
171   return source;
172 }
173
174 void Runtime::LoadingStateChanged(content::WebContents* source) {
175 }
176
177 void Runtime::ToggleFullscreenModeForTab(content::WebContents* web_contents,
178                                          bool enter_fullscreen) {
179   if (enter_fullscreen)
180     fullscreen_options_ |= FULLSCREEN_FOR_TAB;
181   else
182     fullscreen_options_ &= ~FULLSCREEN_FOR_TAB;
183
184   if (enter_fullscreen) {
185     window_->SetFullscreen(true);
186   } else if (!fullscreen_options_ & FULLSCREEN_FOR_LAUNCH) {
187     window_->SetFullscreen(false);
188   }
189 }
190
191 bool Runtime::IsFullscreenForTabOrPending(
192     const content::WebContents* web_contents) const {
193   return (fullscreen_options_ & FULLSCREEN_FOR_TAB) != 0;
194 }
195
196 void Runtime::RequestToLockMouse(content::WebContents* web_contents,
197                                  bool user_gesture,
198                                  bool last_unlocked_by_target) {
199   web_contents->GotResponseToLockMouseRequest(true);
200 }
201
202 void Runtime::CloseContents(content::WebContents* source) {
203   window_->Close();
204 }
205
206 bool Runtime::CanOverscrollContent() const {
207   return false;
208 }
209
210 bool Runtime::PreHandleKeyboardEvent(
211       content::WebContents* source,
212       const content::NativeWebKeyboardEvent& event,
213       bool* is_keyboard_shortcut) {
214   // Escape exits tabbed fullscreen mode.
215   if (event.windowsKeyCode == 27 && IsFullscreenForTabOrPending(source)) {
216     ToggleFullscreenModeForTab(source, false);
217     return true;
218   }
219   return false;
220 }
221
222 void Runtime::HandleKeyboardEvent(
223       content::WebContents* source,
224       const content::NativeWebKeyboardEvent& event) {
225 }
226
227 void Runtime::WebContentsCreated(
228     content::WebContents* source_contents,
229     int64 source_frame_id,
230     const base::string16& frame_name,
231     const GURL& target_url,
232     content::WebContents* new_contents) {
233   Runtime* new_runtime = new Runtime(new_contents, observer_);
234 #if defined(OS_TIZEN)
235   new_runtime->SetRootWindow(root_window_);
236 #endif
237   new_runtime->AttachDefaultWindow();
238 }
239
240 void Runtime::DidNavigateMainFramePostCommit(
241     content::WebContents* web_contents) {
242 }
243
244 content::JavaScriptDialogManager* Runtime::GetJavaScriptDialogManager() {
245   return NULL;
246 }
247
248 void Runtime::ActivateContents(content::WebContents* contents) {
249   contents->GetRenderViewHost()->Focus();
250 }
251
252 void Runtime::DeactivateContents(content::WebContents* contents) {
253   contents->GetRenderViewHost()->Blur();
254 }
255
256 content::ColorChooser* Runtime::OpenColorChooser(
257     content::WebContents* web_contents,
258     SkColor initial_color,
259     const std::vector<content::ColorSuggestion>& suggestions) {
260   return xwalk::ShowColorChooser(web_contents, initial_color);
261 }
262
263 void Runtime::RunFileChooser(
264     content::WebContents* web_contents,
265     const content::FileChooserParams& params) {
266 #if defined(USE_AURA) && defined(OS_LINUX)
267   NOTIMPLEMENTED();
268 #else
269   RuntimeFileSelectHelper::RunFileChooser(web_contents, params);
270 #endif
271 }
272
273 void Runtime::EnumerateDirectory(content::WebContents* web_contents,
274                                  int request_id,
275                                  const base::FilePath& path) {
276 #if defined(USE_AURA) && defined(OS_LINUX)
277   NOTIMPLEMENTED();
278 #else
279   RuntimeFileSelectHelper::EnumerateDirectory(web_contents, request_id, path);
280 #endif
281 }
282
283 void Runtime::DidUpdateFaviconURL(int32 page_id,
284                                   const std::vector<FaviconURL>& candidates) {
285   DLOG(INFO) << "Candidates: ";
286   for (size_t i = 0; i < candidates.size(); ++i)
287     DLOG(INFO) << candidates[i].icon_url.spec();
288
289   if (candidates.empty())
290     return;
291
292   // Avoid using any previous download.
293   weak_ptr_factory_.InvalidateWeakPtrs();
294
295   // We only select the first favicon as the window app icon.
296   FaviconURL favicon = candidates[0];
297   // Passing 0 as the |image_size| parameter results in only receiving the first
298   // bitmap, according to content/public/browser/web_contents.h
299   web_contents()->DownloadImage(
300       favicon.icon_url,
301       true,  // Is a favicon
302       0,     // No maximum size
303       base::Bind(
304           &Runtime::DidDownloadFavicon, weak_ptr_factory_.GetWeakPtr()));
305 }
306
307 void Runtime::DidDownloadFavicon(int id,
308                                  int http_status_code,
309                                  const GURL& image_url,
310                                  const std::vector<SkBitmap>& bitmaps,
311                                  const std::vector<gfx::Size>& sizes) {
312   if (bitmaps.empty())
313     return;
314   app_icon_ = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
315   window_->UpdateIcon(app_icon_);
316 }
317
318 void Runtime::Observe(int type,
319                       const content::NotificationSource& source,
320                       const content::NotificationDetails& details) {
321   if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
322     std::pair<content::NavigationEntry*, bool>* title =
323         content::Details<std::pair<content::NavigationEntry*, bool> >(
324             details).ptr();
325
326     if (title->first) {
327       base::string16 text = title->first->GetTitle();
328       window_->UpdateTitle(text);
329     }
330   }
331 }
332
333 void Runtime::OnWindowDestroyed() {
334   // Runtime should not free itself on Close but be owned
335   // by Application.
336   delete this;
337 }
338
339 void Runtime::RequestMediaAccessPermission(
340     content::WebContents* web_contents,
341     const content::MediaStreamRequest& request,
342     const content::MediaResponseCallback& callback) {
343   XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission(
344       web_contents, request, callback);
345 }
346
347 void Runtime::RenderProcessGone(base::TerminationStatus status) {
348   content::RenderProcessHost* rph = web_contents_->GetRenderProcessHost();
349   VLOG(1) << "RenderProcess id: " << rph->GetID() << " is gone!";
350   XWalkRunner::GetInstance()->OnRenderProcessHostGone(rph);
351 }
352
353 void Runtime::ApplyWindowDefaultParams(NativeAppWindow::CreateParams* params) {
354   if (!params->delegate)
355     params->delegate = this;
356   if (!params->web_contents)
357     params->web_contents = web_contents_.get();
358   if (params->bounds.IsEmpty())
359     params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight);
360 #if defined(OS_TIZEN)
361   if (root_window_)
362     params->parent = root_window_->GetNativeWindow();
363 #endif
364   ApplyFullScreenParam(params);
365 }
366
367 void Runtime::ApplyFullScreenParam(NativeAppWindow::CreateParams* params) {
368   DCHECK(params);
369   // TODO(cmarcelo): This is policy that probably should be moved to outside
370   // Runtime class.
371   CommandLine* cmd_line = CommandLine::ForCurrentProcess();
372   if (cmd_line->HasSwitch(switches::kFullscreen)) {
373     params->state = ui::SHOW_STATE_FULLSCREEN;
374     fullscreen_options_ |= FULLSCREEN_FOR_LAUNCH;
375   }
376 }
377
378 #if defined(OS_TIZEN)
379 void Runtime::CloseRootWindow() {
380   if (root_window_) {
381     root_window_->Close();
382     root_window_ = NULL;
383   }
384 }
385
386 void Runtime::ApplyRootWindowParams(NativeAppWindow::CreateParams* params) {
387   if (!params->delegate)
388     params->delegate = this;
389   if (params->bounds.IsEmpty())
390     params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight);
391   ApplyFullScreenParam(params);
392 }
393
394 void Runtime::InitRootWindow() {
395   if (root_window_)
396     return;
397
398   NativeAppWindow::CreateParams params;
399   ApplyRootWindowParams(&params);
400   root_window_ = NativeAppWindow::Create(params);
401 }
402
403 void Runtime::SetRootWindow(NativeAppWindow* window) {
404   root_window_= window;
405 }
406
407 #endif
408 }  // namespace xwalk