Convert geolocation code to use RenderFrame instead of RenderView.
BUG=304341
[email protected]
Review URL: https://codereview.chromium.org/303503008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274339 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc
index 34b9e84..aec21709 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.cc
+++ b/content/browser/geolocation/geolocation_dispatcher_host.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/metrics/histogram.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_message_filter.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -64,15 +65,15 @@
}
void SendGeolocationPermissionResponse(int render_process_id,
- int render_view_id,
+ int render_frame_id,
int bridge_id,
bool allowed) {
- RenderViewHostImpl* render_view_host =
- RenderViewHostImpl::FromID(render_process_id, render_view_id);
- if (!render_view_host)
+ RenderFrameHost* render_frame_host =
+ RenderFrameHost::FromID(render_process_id, render_frame_id);
+ if (!render_frame_host)
return;
- render_view_host->Send(
- new GeolocationMsg_PermissionSet(render_view_id, bridge_id, allowed));
+ render_frame_host->Send(
+ new GeolocationMsg_PermissionSet(render_frame_id, bridge_id, allowed));
if (allowed)
GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices();
@@ -83,9 +84,7 @@
GeolocationDispatcherHost::GeolocationDispatcherHost(
WebContents* web_contents)
: WebContentsObserver(web_contents),
- watching_requested_(false),
- paused_(false),
- high_accuracy_(false) {
+ paused_(false) {
// This is initialized by WebContentsImpl. Do not add any non-trivial
// initialization here, defer to OnStartUpdating which is triggered whenever
// a javascript geolocation object is actually initialized.
@@ -94,21 +93,28 @@
GeolocationDispatcherHost::~GeolocationDispatcherHost() {
}
+void GeolocationDispatcherHost::RenderFrameDeleted(
+ RenderFrameHost* render_frame_host) {
+ OnStopUpdating(render_frame_host);
+}
+
void GeolocationDispatcherHost::RenderViewHostChanged(
RenderViewHost* old_host,
RenderViewHost* new_host) {
- watching_requested_ = false;
+ updating_frames_.clear();
paused_ = false;
geolocation_subscription_.reset();
}
-bool GeolocationDispatcherHost::OnMessageReceived(const IPC::Message& msg) {
+bool GeolocationDispatcherHost::OnMessageReceived(
+ const IPC::Message& msg, RenderFrameHost* render_frame_host) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcherHost, msg)
- IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest,
- OnCancelPermissionRequest)
+ IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GeolocationDispatcherHost, msg,
+ render_frame_host)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission,
OnRequestPermission)
+ IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest,
+ OnCancelPermissionRequest)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -121,18 +127,25 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
RecordGeopositionErrorCode(geoposition.error_code);
- if (!paused_)
- Send(new GeolocationMsg_PositionUpdated(routing_id(), geoposition));
+ if (paused_)
+ return;
+
+ for (std::map<RenderFrameHost*, bool>::iterator i = updating_frames_.begin();
+ i != updating_frames_.end(); ++i) {
+ i->first->Send(new GeolocationMsg_PositionUpdated(
+ i->first->GetRoutingID(), geoposition));
+ }
}
void GeolocationDispatcherHost::OnRequestPermission(
+ RenderFrameHost* render_frame_host,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture) {
GeolocationPermissionContext* context =
web_contents()->GetBrowserContext()->GetGeolocationPermissionContext();
- int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
- int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID();
+ int render_process_id = render_frame_host->GetProcess()->GetID();
+ int render_frame_id = render_frame_host->GetRoutingID();
if (context) {
context->RequestGeolocationPermission(
web_contents(),
@@ -141,15 +154,16 @@
user_gesture,
base::Bind(&SendGeolocationPermissionResponse,
render_process_id,
- render_view_id,
+ render_frame_id,
bridge_id));
} else {
SendGeolocationPermissionResponse(
- render_process_id, render_view_id, bridge_id, true);
+ render_process_id, render_frame_id, bridge_id, true);
}
}
void GeolocationDispatcherHost::OnCancelPermissionRequest(
+ RenderFrameHost* render_frame_host,
int bridge_id,
const GURL& requesting_frame) {
GeolocationPermissionContext* context =
@@ -161,6 +175,7 @@
}
void GeolocationDispatcherHost::OnStartUpdating(
+ RenderFrameHost* render_frame_host,
const GURL& requesting_frame,
bool enable_high_accuracy) {
// StartUpdating() can be invoked as a result of high-accuracy mode
@@ -169,13 +184,13 @@
"Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
enable_high_accuracy);
- watching_requested_ = true;
- high_accuracy_ = enable_high_accuracy;
+ updating_frames_[render_frame_host] = enable_high_accuracy;
RefreshGeolocationOptions();
}
-void GeolocationDispatcherHost::OnStopUpdating() {
- watching_requested_ = false;
+void GeolocationDispatcherHost::OnStopUpdating(
+ RenderFrameHost* render_frame_host) {
+ updating_frames_.erase(render_frame_host);
RefreshGeolocationOptions();
}
@@ -188,15 +203,24 @@
void GeolocationDispatcherHost::RefreshGeolocationOptions() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (watching_requested_ && !paused_) {
- geolocation_subscription_ = GeolocationProvider::GetInstance()->
- AddLocationUpdateCallback(
- base::Bind(&GeolocationDispatcherHost::OnLocationUpdate,
- base::Unretained(this)),
- high_accuracy_);
- } else {
+ if (updating_frames_.empty() || paused_) {
geolocation_subscription_.reset();
+ return;
}
+
+ bool high_accuracy = false;
+ for (std::map<RenderFrameHost*, bool>::iterator i =
+ updating_frames_.begin(); i != updating_frames_.end(); ++i) {
+ if (i->second) {
+ high_accuracy = true;
+ break;
+ }
+ }
+ geolocation_subscription_ = GeolocationProvider::GetInstance()->
+ AddLocationUpdateCallback(
+ base::Bind(&GeolocationDispatcherHost::OnLocationUpdate,
+ base::Unretained(this)),
+ high_accuracy);
}
} // namespace content
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.h b/content/browser/geolocation/geolocation_dispatcher_host.h
index a73487f0..151ed46 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.h
+++ b/content/browser/geolocation/geolocation_dispatcher_host.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
+#include <map>
+
#include "content/browser/geolocation/geolocation_provider_impl.h"
#include "content/public/browser/web_contents_observer.h"
@@ -29,19 +31,24 @@
private:
// WebContentsObserver
+ virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE;
virtual void RenderViewHostChanged(RenderViewHost* old_host,
RenderViewHost* new_host) OVERRIDE;
- virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
+ virtual bool OnMessageReceived(
+ const IPC::Message& msg, RenderFrameHost* render_frame_host) OVERRIDE;
// Message handlers:
- void OnRequestPermission(int bridge_id,
+ void OnRequestPermission(RenderFrameHost* render_frame_host,
+ int bridge_id,
const GURL& requesting_frame,
bool user_gesture);
- void OnCancelPermissionRequest(int bridge_id,
+ void OnCancelPermissionRequest(RenderFrameHost* render_frame_host,
+ int bridge_id,
const GURL& requesting_frame);
- void OnStartUpdating(const GURL& requesting_frame,
+ void OnStartUpdating(RenderFrameHost* render_frame_host,
+ const GURL& requesting_frame,
bool enable_high_accuracy);
- void OnStopUpdating();
+ void OnStopUpdating(RenderFrameHost* render_frame_host);
// Updates the geolocation provider with the currently required update
// options.
@@ -51,9 +58,10 @@
scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
- bool watching_requested_;
+ // A map from the RenderFrameHosts that have requested geolocation updates to
+ // the type of accuracy they requested (true = high accuracy).
+ std::map<RenderFrameHost*, bool> updating_frames_;
bool paused_;
- bool high_accuracy_;
scoped_ptr<GeolocationProvider::Subscription> geolocation_subscription_;
diff --git a/content/renderer/geolocation_dispatcher.cc b/content/renderer/geolocation_dispatcher.cc
index 7b48ca5..620b057 100644
--- a/content/renderer/geolocation_dispatcher.cc
+++ b/content/renderer/geolocation_dispatcher.cc
@@ -22,8 +22,8 @@
namespace content {
-GeolocationDispatcher::GeolocationDispatcher(RenderViewImpl* render_view)
- : RenderViewObserver(render_view),
+GeolocationDispatcher::GeolocationDispatcher(RenderFrame* render_frame)
+ : RenderFrameObserver(render_frame),
pending_permissions_(new WebGeolocationPermissionRequestManager()),
enable_high_accuracy_(false),
updating_(false) {
diff --git a/content/renderer/geolocation_dispatcher.h b/content/renderer/geolocation_dispatcher.h
index 5a96070..bffa509 100644
--- a/content/renderer/geolocation_dispatcher.h
+++ b/content/renderer/geolocation_dispatcher.h
@@ -6,7 +6,7 @@
#define CONTENT_RENDERER_GEOLOCATION_DISPATCHER_H_
#include "base/memory/scoped_ptr.h"
-#include "content/public/renderer/render_view_observer.h"
+#include "content/public/renderer/render_frame_observer.h"
#include "third_party/WebKit/public/web/WebGeolocationClient.h"
#include "third_party/WebKit/public/web/WebGeolocationController.h"
@@ -18,20 +18,19 @@
}
namespace content {
-class RenderViewImpl;
struct Geoposition;
// GeolocationDispatcher is a delegate for Geolocation messages used by
// WebKit.
-// It's the complement of GeolocationDispatcherHost (owned by RenderViewHost).
-class GeolocationDispatcher : public RenderViewObserver,
+// It's the complement of GeolocationDispatcherHost.
+class GeolocationDispatcher : public RenderFrameObserver,
public blink::WebGeolocationClient {
public:
- explicit GeolocationDispatcher(RenderViewImpl* render_view);
+ explicit GeolocationDispatcher(RenderFrame* render_frame);
virtual ~GeolocationDispatcher();
private:
- // RenderView::Observer implementation.
+ // RenderFrame::Observer implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
// WebGeolocationClient
@@ -55,7 +54,7 @@
// The controller_ is valid for the lifetime of the underlying
// WebCore::GeolocationController. geolocationDestroyed() is
// invoked when the underlying object is destroyed.
- scoped_ptr< blink::WebGeolocationController> controller_;
+ scoped_ptr<blink::WebGeolocationController> controller_;
scoped_ptr<blink::WebGeolocationPermissionRequestManager>
pending_permissions_;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index e891bbac..cfce1ee9 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -52,6 +52,7 @@
#include "content/renderer/context_menu_params_builder.h"
#include "content/renderer/devtools/devtools_agent.h"
#include "content/renderer/dom_automation_controller.h"
+#include "content/renderer/geolocation_dispatcher.h"
#include "content/renderer/history_controller.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/image_loading_helper.h"
@@ -412,6 +413,7 @@
media_player_manager_(NULL),
cdm_manager_(NULL),
#endif
+ geolocation_dispatcher_(NULL),
weak_factory_(this) {
RenderThread::Get()->AddRoute(routing_id_, this);
@@ -2741,7 +2743,9 @@
}
blink::WebGeolocationClient* RenderFrameImpl::geolocationClient() {
- return render_view_->geolocationClient();
+ if (!geolocation_dispatcher_)
+ geolocation_dispatcher_ = new GeolocationDispatcher(this);
+ return geolocation_dispatcher_;
}
void RenderFrameImpl::willStartUsingPeerConnectionHandler(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 7c7cfcb..35e046a 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -58,6 +58,7 @@
namespace content {
class ChildFrameCompositingHelper;
+class GeolocationDispatcher;
class MediaStreamRendererFactory;
class NotificationProvider;
class PepperPluginInstanceImpl;
@@ -616,6 +617,9 @@
RendererCdmManager* cdm_manager_;
#endif
+ // The geolocation dispatcher attached to this view, lazily initialized.
+ GeolocationDispatcher* geolocation_dispatcher_;
+
base::WeakPtrFactory<RenderFrameImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameImpl);
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 7257b00..5ce68b0 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -683,19 +683,19 @@
// Ensure we start with a valid next_page_id_ from the browser.
DCHECK_GE(next_page_id_, 0);
- RenderFrameImpl* main_render_frame = RenderFrameImpl::Create(
- this, params->main_frame_routing_id);
+ main_render_frame_.reset(RenderFrameImpl::Create(
+ this, params->main_frame_routing_id));
// The main frame WebLocalFrame object is closed by
// RenderFrameImpl::frameDetached().
- WebLocalFrame* web_frame = WebLocalFrame::create(main_render_frame);
- main_render_frame->SetWebFrame(web_frame);
+ WebLocalFrame* web_frame = WebLocalFrame::create(main_render_frame_.get());
+ main_render_frame_->SetWebFrame(web_frame);
if (params->proxy_routing_id != MSG_ROUTING_NONE) {
CHECK(params->swapped_out);
RenderFrameProxy* proxy =
RenderFrameProxy::CreateFrameProxy(params->proxy_routing_id,
params->main_frame_routing_id);
- main_render_frame->set_render_frame_proxy(proxy);
+ main_render_frame_->set_render_frame_proxy(proxy);
}
webwidget_ = WebView::create(this);
@@ -757,7 +757,6 @@
webview()->settings()->setAllowConnectingInsecureWebSocket(
command_line.HasSwitch(switches::kAllowInsecureWebSocketFromHttpsOrigin));
- main_render_frame_.reset(main_render_frame);
webview()->setMainFrame(main_render_frame_->GetWebFrame());
main_render_frame_->Initialize();
@@ -3636,8 +3635,10 @@
}
blink::WebGeolocationClient* RenderViewImpl::geolocationClient() {
- if (!geolocation_dispatcher_)
- geolocation_dispatcher_ = new GeolocationDispatcher(this);
+ if (!geolocation_dispatcher_) {
+ geolocation_dispatcher_ = new GeolocationDispatcher(
+ main_render_frame_.get());
+ }
return geolocation_dispatcher_;
}
diff --git a/ui/views/controls/webview/webview_interactive_uitest.cc b/ui/views/controls/webview/webview_interactive_uitest.cc
index c5f65a2..f1179b83 100644
--- a/ui/views/controls/webview/webview_interactive_uitest.cc
+++ b/ui/views/controls/webview/webview_interactive_uitest.cc
@@ -8,6 +8,7 @@
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread.h"
#include "ui/base/ime/text_input_focus_manager.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gl/gl_surface.h"
@@ -18,7 +19,8 @@
class WebViewInteractiveUiTest : public views::test::WidgetTest {
public:
- WebViewInteractiveUiTest() {}
+ WebViewInteractiveUiTest()
+ : ui_thread_(content::BrowserThread::UI, base::MessageLoop::current()) {}
virtual void SetUp() OVERRIDE {
gfx::GLSurface::InitializeOneOffForTests();
@@ -31,6 +33,7 @@
private:
content::TestBrowserContext browser_context_;
views::WebViewTestHelper webview_test_helper_;
+ content::TestBrowserThread ui_thread_;
DISALLOW_COPY_AND_ASSIGN(WebViewInteractiveUiTest);
};