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.
5 #include "xwalk/runtime/browser/runtime.h"
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_process_host.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.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"
33 using content::FaviconURL;
34 using content::WebContents;
40 // The default size for web content area size.
41 const int kDefaultWidth = 840;
42 const int kDefaultHeight = 600;
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();
56 Runtime* Runtime::Create(RuntimeContext* runtime_context,
58 content::SiteInstance* site) {
59 WebContents::CreateParams params(runtime_context, site);
60 params.routing_id = MSG_ROUTING_NONE;
61 WebContents* web_contents = WebContents::Create(params);
63 Runtime* runtime = new Runtime(web_contents, observer);
64 #if defined(OS_TIZEN_MOBILE)
65 runtime->InitRootWindow();
71 Runtime::Runtime(content::WebContents* web_contents, Observer* observer)
72 : WebContentsObserver(web_contents),
73 web_contents_(web_contents),
75 weak_ptr_factory_(this),
76 fullscreen_options_(NO_FULLSCREEN),
78 web_contents_->SetDelegate(this);
79 runtime_context_ = RuntimeContext::FromWebContents(web_contents);
80 content::NotificationService::current()->Notify(
81 xwalk::NOTIFICATION_RUNTIME_OPENED,
82 content::Source<Runtime>(this),
83 content::NotificationService::NoDetails());
84 #if defined(OS_TIZEN_MOBILE)
88 observer_->OnRuntimeAdded(this);
92 content::NotificationService::current()->Notify(
93 xwalk::NOTIFICATION_RUNTIME_CLOSED,
94 content::Source<Runtime>(this),
95 content::NotificationService::NoDetails());
97 observer_->OnRuntimeRemoved(this);
100 void Runtime::AttachDefaultWindow() {
101 NativeAppWindow::CreateParams params;
102 AttachWindow(params);
105 void Runtime::AttachWindow(const NativeAppWindow::CreateParams& params) {
106 #if defined(OS_ANDROID)
110 NativeAppWindow::CreateParams effective_params(params);
111 ApplyWindowDefaultParams(&effective_params);
113 // Set the app icon if it is passed from command line.
114 CommandLine* command_line = CommandLine::ForCurrentProcess();
115 if (command_line->HasSwitch(switches::kAppIcon)) {
116 base::FilePath icon_file =
117 command_line->GetSwitchValuePath(switches::kAppIcon);
118 app_icon_ = xwalk_utils::LoadImageFromFilePath(icon_file);
120 // Otherwise, use the default icon for Crosswalk app.
121 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
122 app_icon_ = rb.GetNativeImageNamed(IDR_XWALK_ICON_48);
126 content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
127 content::Source<content::WebContents>(web_contents_.get()));
129 window_ = NativeAppWindow::Create(effective_params);
130 if (!app_icon_.IsEmpty())
131 window_->UpdateIcon(app_icon_);
133 #if defined(OS_TIZEN_MOBILE)
135 root_window_->Show();
140 void Runtime::LoadURL(const GURL& url) {
141 content::NavigationController::LoadURLParams params(url);
142 params.transition_type = content::PageTransitionFromInt(
143 content::PAGE_TRANSITION_TYPED |
144 content::PAGE_TRANSITION_FROM_ADDRESS_BAR);
145 web_contents_->GetController().LoadURLWithParams(params);
146 web_contents_->Focus();
149 void Runtime::Close() {
154 // Runtime should not free itself on Close but be owned
159 content::RenderProcessHost* Runtime::GetRenderProcessHost() {
160 return web_contents_->GetRenderProcessHost();
163 //////////////////////////////////////////////////////
164 // content::WebContentsDelegate:
165 //////////////////////////////////////////////////////
166 content::WebContents* Runtime::OpenURLFromTab(
167 content::WebContents* source, const content::OpenURLParams& params) {
168 // The only one disposition we would take into consideration.
169 DCHECK(params.disposition == CURRENT_TAB);
170 source->GetController().LoadURL(
171 params.url, params.referrer, params.transition, std::string());
175 void Runtime::LoadingStateChanged(content::WebContents* source,
176 bool to_different_document) {
179 void Runtime::ToggleFullscreenModeForTab(content::WebContents* web_contents,
180 bool enter_fullscreen) {
181 if (enter_fullscreen)
182 fullscreen_options_ |= FULLSCREEN_FOR_TAB;
184 fullscreen_options_ &= ~FULLSCREEN_FOR_TAB;
186 if (enter_fullscreen) {
187 window_->SetFullscreen(true);
188 } else if (!fullscreen_options_ & FULLSCREEN_FOR_LAUNCH) {
189 window_->SetFullscreen(false);
193 bool Runtime::IsFullscreenForTabOrPending(
194 const content::WebContents* web_contents) const {
195 return (fullscreen_options_ & FULLSCREEN_FOR_TAB) != 0;
198 void Runtime::RequestToLockMouse(content::WebContents* web_contents,
200 bool last_unlocked_by_target) {
201 web_contents->GotResponseToLockMouseRequest(true);
204 void Runtime::CloseContents(content::WebContents* source) {
208 bool Runtime::CanOverscrollContent() const {
212 bool Runtime::PreHandleKeyboardEvent(
213 content::WebContents* source,
214 const content::NativeWebKeyboardEvent& event,
215 bool* is_keyboard_shortcut) {
216 // Escape exits tabbed fullscreen mode.
217 if (event.windowsKeyCode == 27 && IsFullscreenForTabOrPending(source)) {
218 ToggleFullscreenModeForTab(source, false);
224 void Runtime::HandleKeyboardEvent(
225 content::WebContents* source,
226 const content::NativeWebKeyboardEvent& event) {
229 void Runtime::WebContentsCreated(
230 content::WebContents* source_contents,
231 int opener_render_frame_id,
232 const base::string16& frame_name,
233 const GURL& target_url,
234 content::WebContents* new_contents) {
235 Runtime* new_runtime = new Runtime(new_contents, observer_);
236 #if defined(OS_TIZEN_MOBILE)
237 new_runtime->SetRootWindow(root_window_);
239 new_runtime->AttachDefaultWindow();
242 void Runtime::DidNavigateMainFramePostCommit(
243 content::WebContents* web_contents) {
246 content::JavaScriptDialogManager* Runtime::GetJavaScriptDialogManager() {
250 void Runtime::ActivateContents(content::WebContents* contents) {
251 contents->GetRenderViewHost()->Focus();
254 void Runtime::DeactivateContents(content::WebContents* contents) {
255 contents->GetRenderViewHost()->Blur();
258 content::ColorChooser* Runtime::OpenColorChooser(
259 content::WebContents* web_contents,
260 SkColor initial_color,
261 const std::vector<content::ColorSuggestion>& suggestions) {
262 return xwalk::ShowColorChooser(web_contents, initial_color);
265 void Runtime::RunFileChooser(
266 content::WebContents* web_contents,
267 const content::FileChooserParams& params) {
268 #if defined(USE_AURA) && defined(OS_LINUX)
271 RuntimeFileSelectHelper::RunFileChooser(web_contents, params);
275 void Runtime::EnumerateDirectory(content::WebContents* web_contents,
277 const base::FilePath& path) {
278 #if defined(USE_AURA) && defined(OS_LINUX)
281 RuntimeFileSelectHelper::EnumerateDirectory(web_contents, request_id, path);
285 void Runtime::DidUpdateFaviconURL(const std::vector<FaviconURL>& candidates) {
286 DLOG(INFO) << "Candidates: ";
287 for (size_t i = 0; i < candidates.size(); ++i)
288 DLOG(INFO) << candidates[i].icon_url.spec();
290 if (candidates.empty())
293 // Avoid using any previous download.
294 weak_ptr_factory_.InvalidateWeakPtrs();
296 // We only select the first favicon as the window app icon.
297 FaviconURL favicon = candidates[0];
298 // Passing 0 as the |image_size| parameter results in only receiving the first
299 // bitmap, according to content/public/browser/web_contents.h
300 web_contents()->DownloadImage(
302 true, // Is a favicon
303 0, // No maximum size
305 &Runtime::DidDownloadFavicon, weak_ptr_factory_.GetWeakPtr()));
308 void Runtime::DidDownloadFavicon(int id,
309 int http_status_code,
310 const GURL& image_url,
311 const std::vector<SkBitmap>& bitmaps,
312 const std::vector<gfx::Size>& sizes) {
315 app_icon_ = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
316 window_->UpdateIcon(app_icon_);
319 void Runtime::Observe(int type,
320 const content::NotificationSource& source,
321 const content::NotificationDetails& details) {
322 if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
323 std::pair<content::NavigationEntry*, bool>* title =
324 content::Details<std::pair<content::NavigationEntry*, bool> >(
328 base::string16 text = title->first->GetTitle();
329 window_->UpdateTitle(text);
334 void Runtime::OnWindowDestroyed() {
335 // Runtime should not free itself on Close but be owned
340 void Runtime::RequestMediaAccessPermission(
341 content::WebContents* web_contents,
342 const content::MediaStreamRequest& request,
343 const content::MediaResponseCallback& callback) {
344 XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission(
345 web_contents, request, callback);
348 void Runtime::ApplyWindowDefaultParams(NativeAppWindow::CreateParams* params) {
349 if (!params->delegate)
350 params->delegate = this;
351 if (!params->web_contents)
352 params->web_contents = web_contents_.get();
353 if (params->bounds.IsEmpty())
354 params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight);
355 #if defined(OS_TIZEN_MOBILE)
357 params->parent = root_window_->GetNativeWindow();
359 ApplyFullScreenParam(params);
362 void Runtime::ApplyFullScreenParam(NativeAppWindow::CreateParams* params) {
364 if (params->state == ui::SHOW_STATE_FULLSCREEN)
365 fullscreen_options_ |= FULLSCREEN_FOR_LAUNCH;
367 fullscreen_options_ &= ~FULLSCREEN_FOR_LAUNCH;
370 #if defined(OS_TIZEN_MOBILE)
371 void Runtime::CloseRootWindow() {
373 root_window_->Close();
378 void Runtime::ApplyRootWindowParams(NativeAppWindow::CreateParams* params) {
379 if (!params->delegate)
380 params->delegate = this;
381 if (params->bounds.IsEmpty())
382 params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight);
383 ApplyFullScreenParam(params);
386 void Runtime::InitRootWindow() {
390 NativeAppWindow::CreateParams params;
391 ApplyRootWindowParams(¶ms);
392 root_window_ = NativeAppWindow::Create(params);
395 void Runtime::SetRootWindow(NativeAppWindow* window) {
396 root_window_= window;