15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/geolocation/geolocation_dispatcher_host.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/metrics/histogram.h"
1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/frame_host/render_frame_host_impl.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_message_filter.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/render_view_host_impl.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/web_contents/web_contents_impl.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_context.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/geoposition.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/geolocation_messages.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Geoposition error codes for reporting in UMA.
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochenum GeopositionErrorCode {
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // NOTE: Do not renumber these as that would confuse interpretation of
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // previously logged data. When making changes, also update the enum list
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // in tools/metrics/histograms/histograms.xml to keep it in sync.
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // There was no error.
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GEOPOSITION_ERROR_CODE_NONE = 0,
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // User denied use of geolocation.
34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1,
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Geoposition could not be determined.
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2,
38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Timeout.
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GEOPOSITION_ERROR_CODE_TIMEOUT = 3,
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // NOTE: Add entries only immediately above this line.
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GEOPOSITION_ERROR_CODE_COUNT = 4
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GeopositionErrorCode code = GEOPOSITION_ERROR_CODE_NONE;
48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  switch (error_code) {
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case Geoposition::ERROR_CODE_NONE:
50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      code = GEOPOSITION_ERROR_CODE_NONE;
51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case Geoposition::ERROR_CODE_PERMISSION_DENIED:
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      code = GEOPOSITION_ERROR_CODE_PERMISSION_DENIED;
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      code = GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE;
57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case Geoposition::ERROR_CODE_TIMEOUT:
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      code = GEOPOSITION_ERROR_CODE_TIMEOUT;
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode",
63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                            code,
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                            GEOPOSITION_ERROR_CODE_COUNT);
65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GeolocationDispatcherHost::PendingPermission::PendingPermission(
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_frame_id,
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int bridge_id)
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : render_frame_id(render_frame_id),
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_process_id(render_process_id),
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bridge_id(bridge_id) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GeolocationDispatcherHost::PendingPermission::~PendingPermission() {
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GeolocationDispatcherHost::GeolocationDispatcherHost(
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    WebContents* web_contents)
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    : WebContentsObserver(web_contents),
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      paused_(false),
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      weak_factory_(this) {
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This is initialized by WebContentsImpl. Do not add any non-trivial
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // initialization here, defer to OnStartUpdating which is triggered whenever
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a javascript geolocation object is actually initialized.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)GeolocationDispatcherHost::~GeolocationDispatcherHost() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GeolocationDispatcherHost::RenderFrameDeleted(
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderFrameHost* render_frame_host) {
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  OnStopUpdating(render_frame_host);
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GeolocationDispatcherHost::RenderViewHostChanged(
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RenderViewHost* old_host,
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RenderViewHost* new_host) {
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  updating_frames_.clear();
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  paused_ = false;
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  geolocation_subscription_.reset();
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool GeolocationDispatcherHost::OnMessageReceived(
10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const IPC::Message& msg, RenderFrameHost* render_frame_host) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GeolocationDispatcherHost, msg,
11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                   render_frame_host)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnRequestPermission)
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest,
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        OnCancelPermissionRequest)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GeolocationHostMsg_StartUpdating, OnStartUpdating)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GeolocationHostMsg_StopUpdating, OnStopUpdating)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GeolocationDispatcherHost::OnLocationUpdate(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Geoposition& geoposition) {
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RecordGeopositionErrorCode(geoposition.error_code);
12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (paused_)
12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (std::map<RenderFrameHost*, bool>::iterator i = updating_frames_.begin();
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)       i != updating_frames_.end(); ++i) {
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* top_frame = i->first;
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    while (top_frame->GetParent()) {
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      top_frame = top_frame->GetParent();
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GetContentClient()->browser()->DidUseGeolocationPermission(
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        web_contents(),
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        i->first->GetLastCommittedURL().GetOrigin(),
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        top_frame->GetLastCommittedURL().GetOrigin());
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    i->first->Send(new GeolocationMsg_PositionUpdated(
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        i->first->GetRoutingID(), geoposition));
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GeolocationDispatcherHost::OnRequestPermission(
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderFrameHost* render_frame_host,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bridge_id,
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const GURL& requesting_frame,
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bool user_gesture) {
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int render_process_id = render_frame_host->GetProcess()->GetID();
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int render_frame_id = render_frame_host->GetRoutingID();
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PendingPermission pending_permission(
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_frame_id, render_process_id, bridge_id);
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pending_permissions_.push_back(pending_permission);
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetContentClient()->browser()->RequestGeolocationPermission(
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      web_contents(),
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bridge_id,
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      requesting_frame,
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      user_gesture,
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&GeolocationDispatcherHost::SendGeolocationPermissionResponse,
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 render_process_id, render_frame_id, bridge_id),
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &pending_permissions_.back().cancel);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GeolocationDispatcherHost::OnCancelPermissionRequest(
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderFrameHost* render_frame_host,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bridge_id,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& requesting_frame) {
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_process_id = render_frame_host->GetProcess()->GetID();
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_frame_id = render_frame_host->GetRoutingID();
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < pending_permissions_.size(); ++i) {
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pending_permissions_[i].render_process_id == render_process_id &&
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].render_frame_id == render_frame_id &&
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].bridge_id == bridge_id) {
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (!pending_permissions_[i].cancel.is_null())
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].cancel.Run();
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_permissions_.erase(pending_permissions_.begin() + i);
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GeolocationDispatcherHost::OnStartUpdating(
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderFrameHost* render_frame_host,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& requesting_frame,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool enable_high_accuracy) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StartUpdating() can be invoked as a result of high-accuracy mode
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // being enabled / disabled. No need to record the dispatcher again.
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN(
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      enable_high_accuracy);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  updating_frames_[render_frame_host] = enable_high_accuracy;
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RefreshGeolocationOptions();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void GeolocationDispatcherHost::OnStopUpdating(
20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    RenderFrameHost* render_frame_host) {
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  updating_frames_.erase(render_frame_host);
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RefreshGeolocationOptions();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GeolocationDispatcherHost::PauseOrResume(bool should_pause) {
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  paused_ = should_pause;
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RefreshGeolocationOptions();
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GeolocationDispatcherHost::RefreshGeolocationOptions() {
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (updating_frames_.empty() || paused_) {
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    geolocation_subscription_.reset();
21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return;
22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  bool high_accuracy = false;
22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  for (std::map<RenderFrameHost*, bool>::iterator i =
22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            updating_frames_.begin(); i != updating_frames_.end(); ++i) {
22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (i->second) {
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      high_accuracy = true;
22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      break;
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  geolocation_subscription_ = GeolocationProvider::GetInstance()->
23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      AddLocationUpdateCallback(
23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          base::Bind(&GeolocationDispatcherHost::OnLocationUpdate,
23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                      base::Unretained(this)),
23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          high_accuracy);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GeolocationDispatcherHost::SendGeolocationPermissionResponse(
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_frame_id,
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int bridge_id,
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool allowed) {
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < pending_permissions_.size(); ++i) {
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pending_permissions_[i].render_process_id == render_process_id &&
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].render_frame_id == render_frame_id &&
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].bridge_id == bridge_id) {
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      RenderFrameHost* render_frame_host =
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          RenderFrameHost::FromID(render_process_id, render_frame_id);
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (render_frame_host) {
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_frame_host->Send(new GeolocationMsg_PermissionSet(
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            render_frame_id, bridge_id, allowed));
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (allowed) {
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        GeolocationProviderImpl::GetInstance()->
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            UserDidOptIntoLocationServices();
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_permissions_.erase(pending_permissions_.begin() + i);
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NOTREACHED();
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
267