| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "apps/app_window.h" | 5 #include "apps/app_window.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "apps/app_delegate.h" | 11 #include "apps/app_delegate.h" |
| 12 #include "apps/app_web_contents_helper.h" |
| 12 #include "apps/app_window_geometry_cache.h" | 13 #include "apps/app_window_geometry_cache.h" |
| 13 #include "apps/app_window_registry.h" | 14 #include "apps/app_window_registry.h" |
| 14 #include "apps/apps_client.h" | 15 #include "apps/apps_client.h" |
| 15 #include "apps/size_constraints.h" | 16 #include "apps/size_constraints.h" |
| 16 #include "apps/ui/native_app_window.h" | 17 #include "apps/ui/native_app_window.h" |
| 17 #include "apps/ui/web_contents_sizer.h" | 18 #include "apps/ui/web_contents_sizer.h" |
| 18 #include "base/command_line.h" | 19 #include "base/command_line.h" |
| 19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/values.h" | 22 #include "base/values.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 34 #include "content/public/browser/render_view_host.h" | 35 #include "content/public/browser/render_view_host.h" |
| 35 #include "content/public/browser/resource_dispatcher_host.h" | 36 #include "content/public/browser/resource_dispatcher_host.h" |
| 36 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 37 #include "content/public/common/content_switches.h" | 38 #include "content/public/common/content_switches.h" |
| 38 #include "content/public/common/media_stream_request.h" | 39 #include "content/public/common/media_stream_request.h" |
| 39 #include "extensions/browser/extension_registry.h" | 40 #include "extensions/browser/extension_registry.h" |
| 40 #include "extensions/browser/extension_system.h" | 41 #include "extensions/browser/extension_system.h" |
| 41 #include "extensions/browser/extensions_browser_client.h" | 42 #include "extensions/browser/extensions_browser_client.h" |
| 42 #include "extensions/browser/process_manager.h" | 43 #include "extensions/browser/process_manager.h" |
| 43 #include "extensions/browser/view_type_utils.h" | 44 #include "extensions/browser/view_type_utils.h" |
| 45 #include "extensions/common/draggable_region.h" |
| 44 #include "extensions/common/extension.h" | 46 #include "extensions/common/extension.h" |
| 45 #include "extensions/common/extension_messages.h" | |
| 46 #include "extensions/common/manifest_handlers/icons_handler.h" | 47 #include "extensions/common/manifest_handlers/icons_handler.h" |
| 47 #include "extensions/common/permissions/permissions_data.h" | 48 #include "extensions/common/permissions/permissions_data.h" |
| 48 #include "grit/theme_resources.h" | 49 #include "grit/theme_resources.h" |
| 49 #include "third_party/skia/include/core/SkRegion.h" | 50 #include "third_party/skia/include/core/SkRegion.h" |
| 50 #include "ui/base/resource/resource_bundle.h" | 51 #include "ui/base/resource/resource_bundle.h" |
| 51 #include "ui/gfx/screen.h" | 52 #include "ui/gfx/screen.h" |
| 52 | 53 |
| 53 #if !defined(OS_MACOSX) | 54 #if !defined(OS_MACOSX) |
| 54 #include "apps/pref_names.h" | 55 #include "apps/pref_names.h" |
| 55 #include "base/prefs/pref_service.h" | 56 #include "base/prefs/pref_service.h" |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 285 |
| 285 // Windows cannot be always-on-top in fullscreen mode for security reasons. | 286 // Windows cannot be always-on-top in fullscreen mode for security reasons. |
| 286 cached_always_on_top_ = new_params.always_on_top; | 287 cached_always_on_top_ = new_params.always_on_top; |
| 287 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) | 288 if (new_params.state == ui::SHOW_STATE_FULLSCREEN) |
| 288 new_params.always_on_top = false; | 289 new_params.always_on_top = false; |
| 289 | 290 |
| 290 requested_transparent_background_ = new_params.transparent_background; | 291 requested_transparent_background_ = new_params.transparent_background; |
| 291 | 292 |
| 292 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); | 293 native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); |
| 293 | 294 |
| 295 helper_.reset(new AppWebContentsHelper( |
| 296 browser_context_, extension_id_, web_contents, app_delegate_.get())); |
| 297 |
| 294 popup_manager_.reset( | 298 popup_manager_.reset( |
| 295 new web_modal::PopupManager(GetWebContentsModalDialogHost())); | 299 new web_modal::PopupManager(GetWebContentsModalDialogHost())); |
| 296 popup_manager_->RegisterWith(web_contents); | 300 popup_manager_->RegisterWith(web_contents); |
| 297 | 301 |
| 298 // Prevent the browser process from shutting down while this window exists. | 302 // Prevent the browser process from shutting down while this window exists. |
| 299 AppsClient::Get()->IncrementKeepAliveCount(); | 303 AppsClient::Get()->IncrementKeepAliveCount(); |
| 300 UpdateExtensionAppIcon(); | 304 UpdateExtensionAppIcon(); |
| 301 AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); | 305 AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); |
| 302 | 306 |
| 303 if (new_params.hidden) { | 307 if (new_params.hidden) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 registrar_.RemoveAll(); | 363 registrar_.RemoveAll(); |
| 360 | 364 |
| 361 // Remove shutdown prevention. | 365 // Remove shutdown prevention. |
| 362 AppsClient::Get()->DecrementKeepAliveCount(); | 366 AppsClient::Get()->DecrementKeepAliveCount(); |
| 363 } | 367 } |
| 364 | 368 |
| 365 void AppWindow::RequestMediaAccessPermission( | 369 void AppWindow::RequestMediaAccessPermission( |
| 366 content::WebContents* web_contents, | 370 content::WebContents* web_contents, |
| 367 const content::MediaStreamRequest& request, | 371 const content::MediaStreamRequest& request, |
| 368 const content::MediaResponseCallback& callback) { | 372 const content::MediaResponseCallback& callback) { |
| 369 const extensions::Extension* extension = GetExtension(); | 373 DCHECK_EQ(AppWindow::web_contents(), web_contents); |
| 370 if (!extension) | 374 helper_->RequestMediaAccessPermission(request, callback); |
| 371 return; | |
| 372 | |
| 373 app_delegate_->RequestMediaAccessPermission( | |
| 374 web_contents, request, callback, extension); | |
| 375 } | 375 } |
| 376 | 376 |
| 377 WebContents* AppWindow::OpenURLFromTab(WebContents* source, | 377 WebContents* AppWindow::OpenURLFromTab(WebContents* source, |
| 378 const content::OpenURLParams& params) { | 378 const content::OpenURLParams& params) { |
| 379 // Don't allow the current tab to be navigated. It would be nice to map all | 379 DCHECK_EQ(web_contents(), source); |
| 380 // anchor tags (even those without target="_blank") to new tabs, but right | 380 return helper_->OpenURLFromTab(params); |
| 381 // now we can't distinguish between those and <meta> refreshes or window.href | |
| 382 // navigations, which we don't want to allow. | |
| 383 // TOOD(mihaip): Can we check for user gestures instead? | |
| 384 WindowOpenDisposition disposition = params.disposition; | |
| 385 if (disposition == CURRENT_TAB) { | |
| 386 AddMessageToDevToolsConsole( | |
| 387 content::CONSOLE_MESSAGE_LEVEL_ERROR, | |
| 388 base::StringPrintf( | |
| 389 "Can't open same-window link to \"%s\"; try target=\"_blank\".", | |
| 390 params.url.spec().c_str())); | |
| 391 return NULL; | |
| 392 } | |
| 393 | |
| 394 // These dispositions aren't really navigations. | |
| 395 if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK || | |
| 396 disposition == IGNORE_ACTION) { | |
| 397 return NULL; | |
| 398 } | |
| 399 | |
| 400 WebContents* contents = | |
| 401 app_delegate_->OpenURLFromTab(browser_context_, source, params); | |
| 402 if (!contents) { | |
| 403 AddMessageToDevToolsConsole( | |
| 404 content::CONSOLE_MESSAGE_LEVEL_ERROR, | |
| 405 base::StringPrintf( | |
| 406 "Can't navigate to \"%s\"; apps do not support navigation.", | |
| 407 params.url.spec().c_str())); | |
| 408 } | |
| 409 | |
| 410 return contents; | |
| 411 } | 381 } |
| 412 | 382 |
| 413 void AppWindow::AddNewContents(WebContents* source, | 383 void AppWindow::AddNewContents(WebContents* source, |
| 414 WebContents* new_contents, | 384 WebContents* new_contents, |
| 415 WindowOpenDisposition disposition, | 385 WindowOpenDisposition disposition, |
| 416 const gfx::Rect& initial_pos, | 386 const gfx::Rect& initial_pos, |
| 417 bool user_gesture, | 387 bool user_gesture, |
| 418 bool* was_blocked) { | 388 bool* was_blocked) { |
| 419 DCHECK(new_contents->GetBrowserContext() == browser_context_); | 389 DCHECK(new_contents->GetBrowserContext() == browser_context_); |
| 420 app_delegate_->AddNewContents(browser_context_, | 390 app_delegate_->AddNewContents(browser_context_, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 Restore(); | 433 Restore(); |
| 464 return; | 434 return; |
| 465 } | 435 } |
| 466 | 436 |
| 467 native_app_window_->HandleKeyboardEvent(event); | 437 native_app_window_->HandleKeyboardEvent(event); |
| 468 } | 438 } |
| 469 | 439 |
| 470 void AppWindow::RequestToLockMouse(WebContents* web_contents, | 440 void AppWindow::RequestToLockMouse(WebContents* web_contents, |
| 471 bool user_gesture, | 441 bool user_gesture, |
| 472 bool last_unlocked_by_target) { | 442 bool last_unlocked_by_target) { |
| 473 const extensions::Extension* extension = GetExtension(); | 443 DCHECK_EQ(AppWindow::web_contents(), web_contents); |
| 474 if (!extension) | 444 helper_->RequestToLockMouse(); |
| 475 return; | |
| 476 | |
| 477 bool has_permission = IsExtensionWithPermissionOrSuggestInConsole( | |
| 478 APIPermission::kPointerLock, | |
| 479 extension, | |
| 480 web_contents->GetRenderViewHost()); | |
| 481 | |
| 482 web_contents->GotResponseToLockMouseRequest(has_permission); | |
| 483 } | 445 } |
| 484 | 446 |
| 485 bool AppWindow::PreHandleGestureEvent(WebContents* source, | 447 bool AppWindow::PreHandleGestureEvent(WebContents* source, |
| 486 const blink::WebGestureEvent& event) { | 448 const blink::WebGestureEvent& event) { |
| 487 // Disable pinch zooming in app windows. | 449 return AppWebContentsHelper::ShouldSuppressGestureEvent(event); |
| 488 return event.type == blink::WebGestureEvent::GesturePinchBegin || | |
| 489 event.type == blink::WebGestureEvent::GesturePinchUpdate || | |
| 490 event.type == blink::WebGestureEvent::GesturePinchEnd; | |
| 491 } | 450 } |
| 492 | 451 |
| 493 void AppWindow::DidFirstVisuallyNonEmptyPaint() { | 452 void AppWindow::DidFirstVisuallyNonEmptyPaint() { |
| 494 first_paint_complete_ = true; | 453 first_paint_complete_ = true; |
| 495 if (show_on_first_paint_) { | 454 if (show_on_first_paint_) { |
| 496 DCHECK(delayed_show_type_ == SHOW_ACTIVE || | 455 DCHECK(delayed_show_type_ == SHOW_ACTIVE || |
| 497 delayed_show_type_ == SHOW_INACTIVE); | 456 delayed_show_type_ == SHOW_INACTIVE); |
| 498 Show(delayed_show_type_); | 457 Show(delayed_show_type_); |
| 499 } | 458 } |
| 500 } | 459 } |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 } | 986 } |
| 1028 | 987 |
| 1029 bool AppWindow::IsWebContentsVisible(content::WebContents* web_contents) { | 988 bool AppWindow::IsWebContentsVisible(content::WebContents* web_contents) { |
| 1030 return app_delegate_->IsWebContentsVisible(web_contents); | 989 return app_delegate_->IsWebContentsVisible(web_contents); |
| 1031 } | 990 } |
| 1032 | 991 |
| 1033 WebContentsModalDialogHost* AppWindow::GetWebContentsModalDialogHost() { | 992 WebContentsModalDialogHost* AppWindow::GetWebContentsModalDialogHost() { |
| 1034 return native_app_window_.get(); | 993 return native_app_window_.get(); |
| 1035 } | 994 } |
| 1036 | 995 |
| 1037 void AppWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, | |
| 1038 const std::string& message) { | |
| 1039 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); | |
| 1040 rvh->Send(new ExtensionMsg_AddMessageToConsole( | |
| 1041 rvh->GetRoutingID(), level, message)); | |
| 1042 } | |
| 1043 | |
| 1044 void AppWindow::SaveWindowPosition() { | 996 void AppWindow::SaveWindowPosition() { |
| 1045 if (window_key_.empty()) | 997 if (window_key_.empty()) |
| 1046 return; | 998 return; |
| 1047 if (!native_app_window_) | 999 if (!native_app_window_) |
| 1048 return; | 1000 return; |
| 1049 | 1001 |
| 1050 AppWindowGeometryCache* cache = | 1002 AppWindowGeometryCache* cache = |
| 1051 AppWindowGeometryCache::Get(browser_context()); | 1003 AppWindowGeometryCache::Get(browser_context()); |
| 1052 | 1004 |
| 1053 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); | 1005 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 region.bounds.x(), | 1104 region.bounds.x(), |
| 1153 region.bounds.y(), | 1105 region.bounds.y(), |
| 1154 region.bounds.right(), | 1106 region.bounds.right(), |
| 1155 region.bounds.bottom(), | 1107 region.bounds.bottom(), |
| 1156 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 1108 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
| 1157 } | 1109 } |
| 1158 return sk_region; | 1110 return sk_region; |
| 1159 } | 1111 } |
| 1160 | 1112 |
| 1161 } // namespace apps | 1113 } // namespace apps |
| OLD | NEW |