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_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"
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(
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);
62 Runtime* runtime = new Runtime(web_contents, observer);
64 runtime->InitRootWindow();
70 Runtime::Runtime(content::WebContents* web_contents, Observer* observer)
71 : WebContentsObserver(web_contents),
72 web_contents_(web_contents),
74 weak_ptr_factory_(this),
75 fullscreen_options_(NO_FULLSCREEN),
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());
87 observer_->OnRuntimeAdded(this);
91 content::NotificationService::current()->Notify(
92 xwalk::NOTIFICATION_RUNTIME_CLOSED,
93 content::Source<Runtime>(this),
94 content::NotificationService::NoDetails());
96 observer_->OnRuntimeRemoved(this);
99 void Runtime::AttachDefaultWindow() {
100 NativeAppWindow::CreateParams params;
101 AttachWindow(params);
104 void Runtime::AttachWindow(const NativeAppWindow::CreateParams& params) {
105 #if defined(OS_ANDROID)
109 NativeAppWindow::CreateParams effective_params(params);
110 ApplyWindowDefaultParams(&effective_params);
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);
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);
125 content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
126 content::Source<content::WebContents>(web_contents_.get()));
128 window_ = NativeAppWindow::Create(effective_params);
129 if (!app_icon_.IsEmpty())
130 window_->UpdateIcon(app_icon_);
132 #if defined(OS_TIZEN)
134 root_window_->Show();
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();
148 void Runtime::Close() {
152 NativeAppWindow* Runtime::window() const {
156 //////////////////////////////////////////////////////
157 // content::WebContentsDelegate:
158 //////////////////////////////////////////////////////
159 content::WebContents* Runtime::OpenURLFromTab(
160 content::WebContents* source, const content::OpenURLParams& params) {
161 // The only one disposition we would take into consideration.
162 DCHECK(params.disposition == CURRENT_TAB);
163 source->GetController().LoadURL(
164 params.url, params.referrer, params.transition, std::string());
168 void Runtime::LoadingStateChanged(content::WebContents* source) {
171 void Runtime::ToggleFullscreenModeForTab(content::WebContents* web_contents,
172 bool enter_fullscreen) {
173 if (enter_fullscreen)
174 fullscreen_options_ |= FULLSCREEN_FOR_TAB;
176 fullscreen_options_ &= ~FULLSCREEN_FOR_TAB;
178 if (enter_fullscreen) {
179 window_->SetFullscreen(true);
180 } else if (!fullscreen_options_ & FULLSCREEN_FOR_LAUNCH) {
181 window_->SetFullscreen(false);
185 bool Runtime::IsFullscreenForTabOrPending(
186 const content::WebContents* web_contents) const {
187 return (fullscreen_options_ & FULLSCREEN_FOR_TAB) != 0;
190 void Runtime::RequestToLockMouse(content::WebContents* web_contents,
192 bool last_unlocked_by_target) {
193 web_contents->GotResponseToLockMouseRequest(true);
196 void Runtime::CloseContents(content::WebContents* source) {
200 bool Runtime::CanOverscrollContent() const {
204 bool Runtime::PreHandleKeyboardEvent(
205 content::WebContents* source,
206 const content::NativeWebKeyboardEvent& event,
207 bool* is_keyboard_shortcut) {
208 // Escape exits tabbed fullscreen mode.
209 if (event.windowsKeyCode == 27 && IsFullscreenForTabOrPending(source)) {
210 ToggleFullscreenModeForTab(source, false);
216 void Runtime::HandleKeyboardEvent(
217 content::WebContents* source,
218 const content::NativeWebKeyboardEvent& event) {
221 void Runtime::WebContentsCreated(
222 content::WebContents* source_contents,
223 int64 source_frame_id,
224 const base::string16& frame_name,
225 const GURL& target_url,
226 content::WebContents* new_contents) {
227 Runtime* new_runtime = new Runtime(new_contents, observer_);
228 #if defined(OS_TIZEN)
229 new_runtime->SetRootWindow(root_window_);
231 new_runtime->AttachDefaultWindow();
234 void Runtime::DidNavigateMainFramePostCommit(
235 content::WebContents* web_contents) {
238 content::JavaScriptDialogManager* Runtime::GetJavaScriptDialogManager() {
242 void Runtime::ActivateContents(content::WebContents* contents) {
243 contents->GetRenderViewHost()->Focus();
246 void Runtime::DeactivateContents(content::WebContents* contents) {
247 contents->GetRenderViewHost()->Blur();
250 content::ColorChooser* Runtime::OpenColorChooser(
251 content::WebContents* web_contents,
252 SkColor initial_color,
253 const std::vector<content::ColorSuggestion>& suggestions) {
254 return xwalk::ShowColorChooser(web_contents, initial_color);
257 void Runtime::RunFileChooser(
258 content::WebContents* web_contents,
259 const content::FileChooserParams& params) {
260 #if defined(USE_AURA) && defined(OS_LINUX)
263 RuntimeFileSelectHelper::RunFileChooser(web_contents, params);
267 void Runtime::EnumerateDirectory(content::WebContents* web_contents,
269 const base::FilePath& path) {
270 #if defined(USE_AURA) && defined(OS_LINUX)
273 RuntimeFileSelectHelper::EnumerateDirectory(web_contents, request_id, path);
277 void Runtime::DidUpdateFaviconURL(int32 page_id,
278 const std::vector<FaviconURL>& candidates) {
279 DLOG(INFO) << "Candidates: ";
280 for (size_t i = 0; i < candidates.size(); ++i)
281 DLOG(INFO) << candidates[i].icon_url.spec();
283 if (candidates.empty())
286 // Avoid using any previous download.
287 weak_ptr_factory_.InvalidateWeakPtrs();
289 // We only select the first favicon as the window app icon.
290 FaviconURL favicon = candidates[0];
291 // Passing 0 as the |image_size| parameter results in only receiving the first
292 // bitmap, according to content/public/browser/web_contents.h
293 web_contents()->DownloadImage(
295 true, // Is a favicon
296 0, // No maximum size
298 &Runtime::DidDownloadFavicon, weak_ptr_factory_.GetWeakPtr()));
301 void Runtime::DidDownloadFavicon(int id,
302 int http_status_code,
303 const GURL& image_url,
304 const std::vector<SkBitmap>& bitmaps,
305 const std::vector<gfx::Size>& sizes) {
308 app_icon_ = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
309 window_->UpdateIcon(app_icon_);
312 void Runtime::Observe(int type,
313 const content::NotificationSource& source,
314 const content::NotificationDetails& details) {
315 if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
316 std::pair<content::NavigationEntry*, bool>* title =
317 content::Details<std::pair<content::NavigationEntry*, bool> >(
321 base::string16 text = title->first->GetTitle();
322 window_->UpdateTitle(text);
327 void Runtime::OnWindowDestroyed() {
331 void Runtime::RequestMediaAccessPermission(
332 content::WebContents* web_contents,
333 const content::MediaStreamRequest& request,
334 const content::MediaResponseCallback& callback) {
335 XWalkMediaCaptureDevicesDispatcher::RunRequestMediaAccessPermission(
336 web_contents, request, callback);
339 void Runtime::RenderProcessGone(base::TerminationStatus status) {
340 content::RenderProcessHost* rph = web_contents_->GetRenderProcessHost();
341 VLOG(1) << "RenderProcess id: " << rph->GetID() << " is gone!";
342 XWalkRunner::GetInstance()->OnRenderProcessHostGone(rph);
345 void Runtime::ApplyWindowDefaultParams(NativeAppWindow::CreateParams* params) {
346 if (!params->delegate)
347 params->delegate = this;
348 if (!params->web_contents)
349 params->web_contents = web_contents_.get();
350 if (params->bounds.IsEmpty())
351 params->bounds = gfx::Rect(0, 0, kDefaultWidth, kDefaultHeight);
352 #if defined(OS_TIZEN)
354 params->parent = root_window_->GetNativeWindow();
356 ApplyFullScreenParam(params);
359 void Runtime::ApplyFullScreenParam(NativeAppWindow::CreateParams* params) {
361 // TODO(cmarcelo): This is policy that probably should be moved to outside
363 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
364 if (cmd_line->HasSwitch(switches::kFullscreen)) {
365 params->state = ui::SHOW_STATE_FULLSCREEN;
366 fullscreen_options_ |= FULLSCREEN_FOR_LAUNCH;
370 #if defined(OS_TIZEN)
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;