Commit 7f5f0bef authored by mgiuca@chromium.org's avatar mgiuca@chromium.org

Refactor AppWindow to enable code re-use with launcher pages.

Created a new class AppWebContentsHelper and moved the implementation of
several WebContentsDelegate methods (those which are not specific to app
windows) from AppWindow to there. AppWindow just calls those methods.
This will enable custom launcher pages to implement WebContentsDelegate
without duplicating a lot of code from AppWindow.

BUG=399116

Review URL: https://codereview.chromium.org/423453002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287302 0039d316-1c4b-4281-b951-d872f2087c98
parent aba955e4
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "apps/app_web_contents_helper.h"
#include "apps/app_delegate.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/suggest_permission_util.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/permissions/api_permission.h"
namespace apps {
AppWebContentsHelper::AppWebContentsHelper(
content::BrowserContext* browser_context,
const std::string& extension_id,
content::WebContents* web_contents,
AppDelegate* app_delegate)
: browser_context_(browser_context),
extension_id_(extension_id),
web_contents_(web_contents),
app_delegate_(app_delegate) {
}
// static
bool AppWebContentsHelper::ShouldSuppressGestureEvent(
const blink::WebGestureEvent& event) {
// Disable pinch zooming in app windows.
return event.type == blink::WebGestureEvent::GesturePinchBegin ||
event.type == blink::WebGestureEvent::GesturePinchUpdate ||
event.type == blink::WebGestureEvent::GesturePinchEnd;
}
content::WebContents* AppWebContentsHelper::OpenURLFromTab(
const content::OpenURLParams& params) const {
// Don't allow the current tab to be navigated. It would be nice to map all
// anchor tags (even those without target="_blank") to new tabs, but right
// now we can't distinguish between those and <meta> refreshes or window.href
// navigations, which we don't want to allow.
// TOOD(mihaip): Can we check for user gestures instead?
WindowOpenDisposition disposition = params.disposition;
if (disposition == CURRENT_TAB) {
AddMessageToDevToolsConsole(
content::CONSOLE_MESSAGE_LEVEL_ERROR,
base::StringPrintf(
"Can't open same-window link to \"%s\"; try target=\"_blank\".",
params.url.spec().c_str()));
return NULL;
}
// These dispositions aren't really navigations.
if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK ||
disposition == IGNORE_ACTION) {
return NULL;
}
content::WebContents* contents =
app_delegate_->OpenURLFromTab(browser_context_, web_contents_, params);
if (!contents) {
AddMessageToDevToolsConsole(
content::CONSOLE_MESSAGE_LEVEL_ERROR,
base::StringPrintf(
"Can't navigate to \"%s\"; apps do not support navigation.",
params.url.spec().c_str()));
}
return contents;
}
void AppWebContentsHelper::RequestToLockMouse() const {
const extensions::Extension* extension = GetExtension();
if (!extension)
return;
bool has_permission = IsExtensionWithPermissionOrSuggestInConsole(
extensions::APIPermission::kPointerLock,
extension,
web_contents_->GetRenderViewHost());
web_contents_->GotResponseToLockMouseRequest(has_permission);
}
void AppWebContentsHelper::RequestMediaAccessPermission(
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) const {
const extensions::Extension* extension = GetExtension();
if (!extension)
return;
app_delegate_->RequestMediaAccessPermission(
web_contents_, request, callback, extension);
}
const extensions::Extension* AppWebContentsHelper::GetExtension() const {
return extensions::ExtensionRegistry::Get(browser_context_)
->enabled_extensions()
.GetByID(extension_id_);
}
void AppWebContentsHelper::AddMessageToDevToolsConsole(
content::ConsoleMessageLevel level,
const std::string& message) const {
content::RenderViewHost* rvh = web_contents_->GetRenderViewHost();
rvh->Send(new ExtensionMsg_AddMessageToConsole(
rvh->GetRoutingID(), level, message));
}
} // namespace apps
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef APPS_APP_WEB_CONTENTS_HELPER_H_
#define APPS_APP_WEB_CONTENTS_HELPER_H_
#include "content/public/common/console_message_level.h"
#include "content/public/common/media_stream_request.h"
namespace blink {
class WebGestureEvent;
}
namespace content {
class BrowserContext;
struct OpenURLParams;
class WebContents;
}
namespace extensions {
class Extension;
}
namespace apps {
class AppDelegate;
// Provides common functionality for apps and launcher pages to respond to
// messages from a WebContents.
class AppWebContentsHelper {
public:
AppWebContentsHelper(content::BrowserContext* browser_context,
const std::string& extension_id,
content::WebContents* web_contents,
AppDelegate* app_delegate);
// Returns true if the given |event| should not be handled by the renderer.
static bool ShouldSuppressGestureEvent(const blink::WebGestureEvent& event);
// Opens a new URL inside the passed in WebContents. See WebContentsDelegate.
content::WebContents* OpenURLFromTab(
const content::OpenURLParams& params) const;
// Requests to lock the mouse. See WebContentsDelegate.
void RequestToLockMouse() const;
// Asks permission to use the camera and/or microphone. See
// WebContentsDelegate.
void RequestMediaAccessPermission(
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) const;
private:
const extensions::Extension* GetExtension() const;
// Helper method to add a message to the renderer's DevTools console.
void AddMessageToDevToolsConsole(content::ConsoleMessageLevel level,
const std::string& message) const;
// The browser context with which this window is associated.
// AppWindowWebContentsDelegate does not own this object.
content::BrowserContext* browser_context_;
const std::string extension_id_;
content::WebContents* web_contents_;
AppDelegate* app_delegate_;
DISALLOW_COPY_AND_ASSIGN(AppWebContentsHelper);
};
} // namespace apps
#endif // APPS_APP_WEB_CONTENTS_HELPER_H_
......@@ -9,6 +9,7 @@
#include <vector>
#include "apps/app_delegate.h"
#include "apps/app_web_contents_helper.h"
#include "apps/app_window_geometry_cache.h"
#include "apps/app_window_registry.h"
#include "apps/apps_client.h"
......@@ -42,8 +43,8 @@
#include "extensions/browser/notification_types.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/draggable_region.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/permissions/permissions_data.h"
#include "grit/theme_resources.h"
......@@ -292,6 +293,9 @@ void AppWindow::Init(const GURL& url,
native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params));
helper_.reset(new AppWebContentsHelper(
browser_context_, extension_id_, web_contents, app_delegate_.get()));
popup_manager_.reset(
new web_modal::PopupManager(GetWebContentsModalDialogHost()));
popup_manager_->RegisterWith(web_contents);
......@@ -368,48 +372,14 @@ void AppWindow::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback) {
const extensions::Extension* extension = GetExtension();
if (!extension)
return;
app_delegate_->RequestMediaAccessPermission(
web_contents, request, callback, extension);
DCHECK_EQ(AppWindow::web_contents(), web_contents);
helper_->RequestMediaAccessPermission(request, callback);
}
WebContents* AppWindow::OpenURLFromTab(WebContents* source,
const content::OpenURLParams& params) {
// Don't allow the current tab to be navigated. It would be nice to map all
// anchor tags (even those without target="_blank") to new tabs, but right
// now we can't distinguish between those and <meta> refreshes or window.href
// navigations, which we don't want to allow.
// TOOD(mihaip): Can we check for user gestures instead?
WindowOpenDisposition disposition = params.disposition;
if (disposition == CURRENT_TAB) {
AddMessageToDevToolsConsole(
content::CONSOLE_MESSAGE_LEVEL_ERROR,
base::StringPrintf(
"Can't open same-window link to \"%s\"; try target=\"_blank\".",
params.url.spec().c_str()));
return NULL;
}
// These dispositions aren't really navigations.
if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK ||
disposition == IGNORE_ACTION) {
return NULL;
}
WebContents* contents =
app_delegate_->OpenURLFromTab(browser_context_, source, params);
if (!contents) {
AddMessageToDevToolsConsole(
content::CONSOLE_MESSAGE_LEVEL_ERROR,
base::StringPrintf(
"Can't navigate to \"%s\"; apps do not support navigation.",
params.url.spec().c_str()));
}
return contents;
DCHECK_EQ(web_contents(), source);
return helper_->OpenURLFromTab(params);
}
void AppWindow::AddNewContents(WebContents* source,
......@@ -472,24 +442,13 @@ void AppWindow::HandleKeyboardEvent(
void AppWindow::RequestToLockMouse(WebContents* web_contents,
bool user_gesture,
bool last_unlocked_by_target) {
const extensions::Extension* extension = GetExtension();
if (!extension)
return;
bool has_permission = IsExtensionWithPermissionOrSuggestInConsole(
APIPermission::kPointerLock,
extension,
web_contents->GetRenderViewHost());
web_contents->GotResponseToLockMouseRequest(has_permission);
DCHECK_EQ(AppWindow::web_contents(), web_contents);
helper_->RequestToLockMouse();
}
bool AppWindow::PreHandleGestureEvent(WebContents* source,
const blink::WebGestureEvent& event) {
// Disable pinch zooming in app windows.
return event.type == blink::WebGestureEvent::GesturePinchBegin ||
event.type == blink::WebGestureEvent::GesturePinchUpdate ||
event.type == blink::WebGestureEvent::GesturePinchEnd;
return AppWebContentsHelper::ShouldSuppressGestureEvent(event);
}
void AppWindow::DidFirstVisuallyNonEmptyPaint() {
......@@ -1036,13 +995,6 @@ WebContentsModalDialogHost* AppWindow::GetWebContentsModalDialogHost() {
return native_app_window_.get();
}
void AppWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level,
const std::string& message) {
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
rvh->Send(new ExtensionMsg_AddMessageToConsole(
rvh->GetRoutingID(), level, message));
}
void AppWindow::SaveWindowPosition() {
if (window_key_.empty())
return;
......
......@@ -17,7 +17,6 @@
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/console_message_level.h"
#include "extensions/browser/extension_icon_image.h"
#include "ui/base/ui_base_types.h" // WindowShowState
#include "ui/gfx/image/image.h"
......@@ -50,6 +49,7 @@ class BaseWindow;
namespace apps {
class AppDelegate;
class AppWebContentsHelper;
class NativeAppWindow;
// Manages the web contents for app windows. The implementation for this
......@@ -427,10 +427,6 @@ class AppWindow : public content::NotificationObserver,
virtual bool IsWebContentsVisible(content::WebContents* web_contents)
OVERRIDE;
// Helper method to add a message to the renderer's DevTools console.
void AddMessageToDevToolsConsole(content::ConsoleMessageLevel level,
const std::string& message);
// Saves the window geometry/position/screen bounds.
void SaveWindowPosition();
......@@ -519,6 +515,7 @@ class AppWindow : public content::NotificationObserver,
scoped_ptr<AppWindowContents> app_window_contents_;
scoped_ptr<AppDelegate> app_delegate_;
scoped_ptr<Delegate> delegate_;
scoped_ptr<AppWebContentsHelper> helper_;
// Manages popup windows (bubbles, tab-modals) visible overlapping the
// app window.
......
......@@ -44,6 +44,8 @@
'app_window_geometry_cache.h',
'app_window_registry.cc',
'app_window_registry.h',
'app_web_contents_helper.cc',
'app_web_contents_helper.h',
'apps_client.cc',
'apps_client.h',
'browser_context_keyed_service_factories.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment