Upstream version 11.40.277.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 "base/strings/utf_string_conversions.h"
13 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/notification_details.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/render_frame_host.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "grit/xwalk_resources.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/image/image_skia.h"
23 #include "ui/gfx/native_widget_types.h"
24 #include "xwalk/runtime/browser/image_util.h"
25 #include "xwalk/runtime/browser/media/media_capture_devices_dispatcher.h"
26 #include "xwalk/runtime/browser/runtime_file_select_helper.h"
27 #include "xwalk/runtime/browser/ui/color_chooser.h"
28 #include "xwalk/runtime/browser/xwalk_browser_context.h"
29 #include "xwalk/runtime/browser/xwalk_runner.h"
30 #include "xwalk/runtime/common/xwalk_notification_types.h"
31 #include "xwalk/runtime/common/xwalk_switches.h"
32
33 #if defined(OS_TIZEN)
34 #include "content/public/browser/site_instance.h"
35 #include "xwalk/application/browser/application.h"
36 #include "xwalk/application/browser/application_system.h"
37 #include "xwalk/application/browser/application_service.h"
38 #endif
39
40 #if !defined(OS_ANDROID)
41 #include "xwalk/runtime/browser/runtime_ui_delegate.h"
42 #endif
43
44 using content::FaviconURL;
45 using content::WebContents;
46
47 namespace xwalk {
48
49 // static
50 Runtime* Runtime::Create(XWalkBrowserContext* browser_context,
51                          content::SiteInstance* site) {
52   WebContents::CreateParams params(browser_context, site);
53   params.routing_id = MSG_ROUTING_NONE;
54   WebContents* web_contents = WebContents::Create(params);
55
56   return new Runtime(web_contents);
57 }
58
59 Runtime::Runtime(content::WebContents* web_contents)
60     : WebContentsObserver(web_contents),
61       web_contents_(web_contents),
62       fullscreen_options_(NO_FULLSCREEN),
63       remote_debugging_enabled_(false),
64       ui_delegate_(nullptr),
65       observer_(nullptr),
66       weak_ptr_factory_(this) {
67   web_contents_->SetDelegate(this);
68   registrar_.Add(this,
69                  content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
70                  content::Source<content::WebContents>(web_contents_.get()));
71 }
72
73 Runtime::~Runtime() {
74   if (ui_delegate_)
75     ui_delegate_->DeleteDelegate();
76 }
77
78 void Runtime::LoadURL(const GURL& url) {
79   content::NavigationController::LoadURLParams params(url);
80   params.transition_type = ui::PageTransitionFromInt(
81       ui::PAGE_TRANSITION_TYPED |
82       ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
83   web_contents_->GetController().LoadURLWithParams(params);
84   web_contents_->Focus();
85 }
86
87 void Runtime::Show() {
88   if (ui_delegate_)
89     ui_delegate_->Show();
90 }
91
92 void Runtime::Close() {
93   web_contents_->Close();
94 }
95
96 NativeAppWindow* Runtime::window() {
97   if (ui_delegate_)
98     return static_cast<DefaultRuntimeUIDelegate*>(ui_delegate_)->window();
99   return nullptr;
100 }
101
102 content::RenderProcessHost* Runtime::GetRenderProcessHost() {
103   return web_contents_->GetRenderProcessHost();
104 }
105
106 //////////////////////////////////////////////////////
107 // content::WebContentsDelegate:
108 //////////////////////////////////////////////////////
109 content::WebContents* Runtime::OpenURLFromTab(
110     content::WebContents* source, const content::OpenURLParams& params) {
111 #if defined(OS_ANDROID)
112   DCHECK(params.disposition == CURRENT_TAB);
113   source->GetController().LoadURL(
114       params.url, params.referrer, params.transition, std::string());
115 #else
116   if (params.disposition == CURRENT_TAB) {
117     source->GetController().LoadURL(
118         params.url, params.referrer, params.transition, std::string());
119   } else if (params.disposition == NEW_WINDOW ||
120              params.disposition == NEW_POPUP ||
121              params.disposition == NEW_FOREGROUND_TAB ||
122              params.disposition == NEW_BACKGROUND_TAB) {
123     // TODO(xinchao): Excecuting JaveScript code is a temporary solution,
124     // need to be implemented by creating a new runtime window instead.
125     web_contents()->GetFocusedFrame()->ExecuteJavaScript(
126         base::UTF8ToUTF16("window.open('" + params.url.spec() + "')"));
127   }
128 #endif
129   return source;
130 }
131
132 void Runtime::LoadingStateChanged(content::WebContents* source,
133                                   bool to_different_document) {
134 }
135
136 void Runtime::ToggleFullscreenModeForTab(content::WebContents* web_contents,
137                                          bool enter_fullscreen) {
138   if (enter_fullscreen)
139     fullscreen_options_ |= FULLSCREEN_FOR_TAB;
140   else
141     fullscreen_options_ &= ~FULLSCREEN_FOR_TAB;
142   if (ui_delegate_)
143     ui_delegate_->SetFullscreen(
144         enter_fullscreen || (fullscreen_options_ & FULLSCREEN_FOR_LAUNCH));
145 }
146
147 bool Runtime::IsFullscreenForTabOrPending(
148     const content::WebContents* web_contents) const {
149   return (fullscreen_options_ & FULLSCREEN_FOR_TAB) != 0;
150 }
151
152 void Runtime::RequestToLockMouse(content::WebContents* web_contents,
153                                  bool user_gesture,
154                                  bool last_unlocked_by_target) {
155   web_contents->GotResponseToLockMouseRequest(true);
156 }
157
158 void Runtime::CloseContents(content::WebContents* source) {
159   if (ui_delegate_)
160     ui_delegate_->Close();
161
162   if (observer_)
163     observer_->OnRuntimeClosed(this);
164 }
165
166 bool Runtime::CanOverscrollContent() const {
167   return false;
168 }
169
170 bool Runtime::PreHandleKeyboardEvent(
171       content::WebContents* source,
172       const content::NativeWebKeyboardEvent& event,
173       bool* is_keyboard_shortcut) {
174   // Escape exits tabbed fullscreen mode.
175   if (event.windowsKeyCode == 27 && IsFullscreenForTabOrPending(source)) {
176     ToggleFullscreenModeForTab(source, false);
177     return true;
178   }
179   return false;
180 }
181
182 void Runtime::HandleKeyboardEvent(
183       content::WebContents* source,
184       const content::NativeWebKeyboardEvent& event) {
185 }
186
187 void Runtime::WebContentsCreated(
188     content::WebContents* source_contents,
189     int opener_render_frame_id,
190     const base::string16& frame_name,
191     const GURL& target_url,
192     content::WebContents* new_contents) {
193   if (observer_)
194     observer_->OnNewRuntimeAdded(new Runtime(new_contents));
195   else
196     LOG(WARNING) << "New web contents is left unhandled.";
197 }
198
199 void Runtime::DidNavigateMainFramePostCommit(
200     content::WebContents* web_contents) {
201 }
202
203 content::JavaScriptDialogManager* Runtime::GetJavaScriptDialogManager() {
204   return NULL;
205 }
206
207 void Runtime::ActivateContents(content::WebContents* contents) {
208   contents->GetRenderViewHost()->Focus();
209 }
210
211 void Runtime::DeactivateContents(content::WebContents* contents) {
212   contents->GetRenderViewHost()->Blur();
213 }
214
215 content::ColorChooser* Runtime::OpenColorChooser(
216     content::WebContents* web_contents,
217     SkColor initial_color,
218     const std::vector<content::ColorSuggestion>& suggestions) {
219 #if defined(TOOLKIT_VIEWS)
220   return xwalk::ShowColorChooser(web_contents, initial_color);
221 #else
222   return WebContentsDelegate::OpenColorChooser(web_contents,
223                                                initial_color,
224                                                suggestions);
225 #endif
226 }
227
228 void Runtime::RunFileChooser(
229     content::WebContents* web_contents,
230     const content::FileChooserParams& params) {
231 #if defined(USE_AURA) && defined(OS_LINUX)
232   NOTIMPLEMENTED();
233 #else
234   RuntimeFileSelectHelper::RunFileChooser(web_contents, params);
235 #endif
236 }
237
238 void Runtime::EnumerateDirectory(content::WebContents* web_contents,
239                                  int request_id,
240                                  const base::FilePath& path) {
241 #if defined(USE_AURA) && defined(OS_LINUX)
242   NOTIMPLEMENTED();
243 #else
244   RuntimeFileSelectHelper::EnumerateDirectory(web_contents, request_id, path);
245 #endif
246 }
247
248 void Runtime::DidUpdateFaviconURL(const std::vector<FaviconURL>& candidates) {
249   DLOG(INFO) << "Candidates: ";
250   for (size_t i = 0; i < candidates.size(); ++i)
251     DLOG(INFO) << candidates[i].icon_url.spec();
252
253   if (candidates.empty())
254     return;
255
256   // Avoid using any previous download.
257   weak_ptr_factory_.InvalidateWeakPtrs();
258
259   // We only select the first favicon as the window app icon.
260   FaviconURL favicon = candidates[0];
261   // Passing 0 as the |image_size| parameter results in only receiving the first
262   // bitmap, according to content/public/browser/web_contents.h
263   web_contents()->DownloadImage(
264       favicon.icon_url,
265       true,  // Is a favicon
266       0,     // No maximum size
267       base::Bind(
268           &Runtime::DidDownloadFavicon, weak_ptr_factory_.GetWeakPtr()));
269 }
270
271 void Runtime::DidDownloadFavicon(int id,
272                                  int http_status_code,
273                                  const GURL& image_url,
274                                  const std::vector<SkBitmap>& bitmaps,
275                                  const std::vector<gfx::Size>& sizes) {
276   if (bitmaps.empty())
277     return;
278   app_icon_ = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
279   if (ui_delegate_)
280     ui_delegate_->UpdateIcon(app_icon_);
281 }
282
283 void Runtime::Observe(int type,
284                       const content::NotificationSource& source,
285                       const content::NotificationDetails& details) {
286   if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
287     std::pair<content::NavigationEntry*, bool>* title =
288         content::Details<std::pair<content::NavigationEntry*, bool> >(
289             details).ptr();
290
291     if (title->first && ui_delegate_)
292       ui_delegate_->UpdateTitle(title->first->GetTitle());
293   }
294 }
295
296 void Runtime::RequestMediaAccessPermission(
297     content::WebContents* web_contents,
298     const content::MediaStreamRequest& request,
299     const content::MediaResponseCallback& callback) {
300   XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission(
301       web_contents, request, callback);
302 }
303
304 }  // namespace xwalk