summaryrefslogtreecommitdiffstats
path: root/chrome/browser/geolocation
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/geolocation')
-rw-r--r--chrome/browser/geolocation/geolocation_dispatcher_host.cc154
-rw-r--r--chrome/browser/geolocation/geolocation_dispatcher_host.h77
-rw-r--r--chrome/browser/geolocation/geolocation_permission_context.cc291
-rw-r--r--chrome/browser/geolocation/geolocation_permission_context.h88
-rw-r--r--chrome/browser/geolocation/location_arbitrator.cc4
-rw-r--r--chrome/browser/geolocation/location_arbitrator.h4
-rw-r--r--chrome/browser/geolocation/location_arbitrator_unittest.cc14
-rw-r--r--chrome/browser/geolocation/location_provider.h3
-rw-r--r--chrome/browser/geolocation/network_location_provider.cc14
-rw-r--r--chrome/browser/geolocation/network_location_provider.h8
-rw-r--r--chrome/browser/geolocation/network_location_provider_unittest.cc2
-rw-r--r--chrome/browser/geolocation/network_location_request.cc16
-rw-r--r--chrome/browser/geolocation/network_location_request.h3
13 files changed, 645 insertions, 33 deletions
diff --git a/chrome/browser/geolocation/geolocation_dispatcher_host.cc b/chrome/browser/geolocation/geolocation_dispatcher_host.cc
new file mode 100644
index 0000000..1217224
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_dispatcher_host.cc
@@ -0,0 +1,154 @@
+// Copyright (c) 2010 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 "chrome/browser/geolocation/geolocation_dispatcher_host.h"
+
+#include "chrome/common/geoposition.h"
+#include "chrome/browser/geolocation/geolocation_permission_context.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_view_host_notification_task.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "chrome/common/render_messages.h"
+
+GeolocationDispatcherHost::GeolocationDispatcherHost(
+ int resource_message_filter_process_id,
+ GeolocationPermissionContext* geolocation_permission_context)
+ : resource_message_filter_process_id_(resource_message_filter_process_id),
+ geolocation_permission_context_(geolocation_permission_context) {
+ // This is initialized by ResourceMessageFilter. Do not add any non-trivial
+ // initialization here, defer to OnRegisterBridge which is triggered whenever
+ // a javascript geolocation object is actually initialized.
+}
+
+GeolocationDispatcherHost::~GeolocationDispatcherHost() {
+}
+
+bool GeolocationDispatcherHost::OnMessageReceived(
+ const IPC::Message& msg, bool* msg_was_ok) {
+ *msg_was_ok = true;
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(GeolocationDispatcherHost, msg, *msg_was_ok)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_RegisterDispatcher,
+ OnRegisterDispatcher)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_UnregisterDispatcher,
+ OnUnregisterDispatcher)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_RequestPermission,
+ OnRequestPermission)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_StartUpdating,
+ OnStartUpdating)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_StopUpdating,
+ OnStopUpdating)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_Suspend,
+ OnSuspend)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_Geolocation_Resume,
+ OnResume)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void GeolocationDispatcherHost::NotifyPositionUpdated(
+ const Geoposition& geoposition) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationDispatcherHost::NotifyPositionUpdated,
+ geoposition));
+ return;
+ }
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ for (std::set<GeolocationServiceRenderId>::iterator geo =
+ geolocation_renderers_.begin();
+ geo != geolocation_renderers_.end();
+ ++geo) {
+ IPC::Message* message;
+ if (geoposition.error_code != Geoposition::ERROR_CODE_NONE) {
+ message = new ViewMsg_Geolocation_PositionUpdated(
+ geo->route_id, geoposition);
+ } else {
+ message = new ViewMsg_Geolocation_Error(
+ geo->route_id, geoposition.error_code,
+ WideToUTF8(geoposition.error_message));
+ }
+ CallRenderViewHost(
+ geo->process_id, geo->route_id, &RenderViewHost::Send, message);
+ }
+}
+
+void GeolocationDispatcherHost::OnRegisterDispatcher(int route_id) {
+ // TODO(bulach): is this the right way to get the RendererViewHost process id
+ // to be used by RenderViewHost::FromID?
+ RegisterDispatcher(resource_message_filter_process_id_, route_id);
+}
+
+void GeolocationDispatcherHost::OnUnregisterDispatcher(int route_id) {
+ UnregisterDispatcher(resource_message_filter_process_id_, route_id);
+}
+
+void GeolocationDispatcherHost::OnRequestPermission(
+ int route_id, int bridge_id, const GURL& origin) {
+ LOG(INFO) << "permission request";
+ geolocation_permission_context_->RequestGeolocationPermission(
+ resource_message_filter_process_id_, route_id, bridge_id, origin);
+}
+
+void GeolocationDispatcherHost::OnStartUpdating(
+ int route_id, int bridge_id, bool high_accuracy) {
+ LOG(INFO) << "start updating" << route_id;
+ // TODO(bulach): connect this with GeolocationServiceProvider.
+}
+
+void GeolocationDispatcherHost::OnStopUpdating(int route_id, int bridge_id) {
+ LOG(INFO) << "stop updating" << route_id;
+ // TODO(bulach): connect this with GeolocationServiceProvider.
+}
+
+void GeolocationDispatcherHost::OnSuspend(int route_id, int bridge_id) {
+ LOG(INFO) << "suspend" << route_id;
+ // TODO(bulach): connect this with GeolocationServiceProvider.
+}
+
+void GeolocationDispatcherHost::OnResume(int route_id, int bridge_id) {
+ LOG(INFO) << "resume" << route_id;
+ // TODO(bulach): connect this with GeolocationServiceProvider.
+}
+
+void GeolocationDispatcherHost::RegisterDispatcher(
+ int process_id, int route_id) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationDispatcherHost::RegisterDispatcher, process_id,
+ route_id));
+ return;
+ }
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+
+ GeolocationServiceRenderId geolocation_render_id(process_id, route_id);
+ std::set<GeolocationServiceRenderId>::const_iterator existing =
+ geolocation_renderers_.find(geolocation_render_id);
+ DCHECK(existing == geolocation_renderers_.end());
+ geolocation_renderers_.insert(geolocation_render_id);
+}
+
+void GeolocationDispatcherHost::UnregisterDispatcher(
+ int process_id, int route_id) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationDispatcherHost::UnregisterDispatcher, process_id,
+ route_id));
+ return;
+ }
+ GeolocationServiceRenderId geolocation_render_id(process_id, route_id);
+ std::set<GeolocationServiceRenderId>::iterator existing =
+ geolocation_renderers_.find(geolocation_render_id);
+ DCHECK(existing != geolocation_renderers_.end());
+ geolocation_renderers_.erase(existing);
+}
diff --git a/chrome/browser/geolocation/geolocation_dispatcher_host.h b/chrome/browser/geolocation/geolocation_dispatcher_host.h
new file mode 100644
index 0000000..8bd7eaf
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_dispatcher_host.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
+#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "ipc/ipc_message.h"
+
+class GeolocationPermissionContext;
+struct Geoposition;
+class GURL;
+class ResourceMessageFilter;
+
+// GeolocationDispatcherHost is a delegate for Geolocation messages used by
+// ResourceMessageFilter.
+// It's the complement of GeolocationDispatcher (owned by RenderView).
+class GeolocationDispatcherHost
+ : public base::RefCountedThreadSafe<GeolocationDispatcherHost> {
+ public:
+ GeolocationDispatcherHost(
+ int resource_message_filter_process_id,
+ GeolocationPermissionContext* geolocation_permission_context);
+
+ // Called to possibly handle the incoming IPC message. Returns true if
+ // handled. Called in the browser process.
+ bool OnMessageReceived(const IPC::Message& msg, bool* msg_was_ok);
+
+ // Tells the render view that a new geolocation position is available.
+ void NotifyPositionUpdated(const Geoposition& geoposition);
+
+ private:
+ friend class base::RefCountedThreadSafe<GeolocationDispatcherHost>;
+ ~GeolocationDispatcherHost();
+
+ void OnRegisterDispatcher(int route_id);
+ void OnUnregisterDispatcher(int route_id);
+ void OnRequestPermission(int route_id, int bridge_id, const GURL& origin);
+ void OnStartUpdating(int route_id, int bridge_id, bool high_accuracy);
+ void OnStopUpdating(int route_id, int bridge_id);
+ void OnSuspend(int route_id, int bridge_id);
+ void OnResume(int route_id, int bridge_id);
+
+ // Registers the bridge created in the renderer side. They'll delegate to the
+ // UI thread if not already in there.
+ void RegisterDispatcher(int process_id, int route_id);
+ void UnregisterDispatcher(int process_id, int route_id);
+
+ int resource_message_filter_process_id_;
+ scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
+
+ struct GeolocationServiceRenderId {
+ int process_id;
+ int route_id;
+ GeolocationServiceRenderId(int process_id, int route_id)
+ : process_id(process_id), route_id(route_id) {
+ }
+ bool operator==(const GeolocationServiceRenderId& rhs) const {
+ return process_id == rhs.route_id &&
+ route_id == rhs.route_id;
+ }
+ bool operator<(const GeolocationServiceRenderId& rhs) const {
+ return process_id < rhs.route_id &&
+ route_id < rhs.route_id;
+ }
+ };
+ // Only used on the UI thread.
+ std::set<GeolocationServiceRenderId> geolocation_renderers_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost);
+};
+
+#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
diff --git a/chrome/browser/geolocation/geolocation_permission_context.cc b/chrome/browser/geolocation/geolocation_permission_context.cc
new file mode 100644
index 0000000..853e0a7
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_permission_context.cc
@@ -0,0 +1,291 @@
+// Copyright (c) 2010 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 "chrome/browser/geolocation/geolocation_permission_context.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/file_util.h"
+#include "googleurl/src/gurl.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/geolocation/geolocation_dispatcher_host.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/render_view_host_notification_task.h"
+#include "chrome/browser/tab_contents/infobar_delegate.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/json_value_serializer.h"
+#include "chrome/common/render_messages.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+
+namespace {
+
+const FilePath::CharType kGeolocationPermissionPath[] =
+ FILE_PATH_LITERAL("Geolocation");
+
+const wchar_t kAllowedDictionaryKey[] = L"allowed";
+
+// This is the delegate used to display the confirmation info bar.
+class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+ GeolocationConfirmInfoBarDelegate(
+ TabContents* tab_contents, GeolocationPermissionContext* context,
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin)
+ : ConfirmInfoBarDelegate(tab_contents), context_(context),
+ render_process_id_(render_process_id), render_view_id_(render_view_id),
+ bridge_id_(bridge_id), origin_(origin) {
+ }
+
+ // ConfirmInfoBarDelegate
+ virtual Type GetInfoBarType() { return INFO_TYPE; }
+ virtual bool Accept() { return SetPermission(true); }
+ virtual bool Cancel() { return SetPermission(false); }
+ virtual int GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; }
+
+ virtual std::wstring GetButtonLabel(InfoBarButton button) const {
+ switch (button) {
+ case BUTTON_OK:
+ return l10n_util::GetString(IDS_GEOLOCATION_ALLOW_BUTTON);
+ case BUTTON_CANCEL:
+ return l10n_util::GetString(IDS_GEOLOCATION_DENY_BUTTON);
+ default:
+ // All buttons are labeled above.
+ NOTREACHED() << "Bad button id " << button;
+ return L"";
+ }
+ }
+
+ virtual std::wstring GetMessageText() const {
+ return l10n_util::GetStringF(
+ IDS_GEOLOCATION_INFOBAR_QUESTION, UTF8ToWide(origin_.host()));
+ }
+
+ virtual SkBitmap* GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_GEOLOCATION_INFOBAR_ICON);
+ }
+
+ private:
+ bool SetPermission(bool confirm) {
+ context_->SetPermission(
+ render_process_id_, render_view_id_, bridge_id_, origin_, confirm);
+ return true;
+ }
+
+ scoped_refptr<GeolocationPermissionContext> context_;
+ int render_process_id_;
+ int render_view_id_;
+ int bridge_id_;
+ GURL origin_;
+};
+
+// TODO(bulach): use HostContentSettingsMap instead!
+FilePath::StringType StdStringToFilePathString(const std::string& std_string) {
+#if defined(OS_WIN)
+ return UTF8ToWide(std_string);
+#else
+ return std_string;
+#endif
+}
+
+std::string GURLToCacheKey(const GURL& gurl) {
+ return gurl.host();
+}
+
+// Returns true if permission was successfully read from file, and *allowed
+// be set accordingly.
+// Returns false otherwise.
+bool ReadPermissionFromFile(
+ const GURL& origin, const FilePath& permissions_path, bool* allowed) {
+ DCHECK(allowed);
+ *allowed = false;
+ // TODO(bulach): this is probably wrong! is there any utility to convert a URL
+ // to FilePath?
+ FilePath permission_file(
+ permissions_path.Append(StdStringToFilePathString(
+ GURLToCacheKey(origin))));
+ if (!file_util::PathExists(permission_file))
+ return false;
+ JSONFileValueSerializer serializer(permission_file);
+ scoped_ptr<Value> root_value(serializer.Deserialize(NULL));
+ bool ret = root_value.get() &&
+ root_value->GetType() == Value::TYPE_DICTIONARY;
+ DictionaryValue* dictionary = static_cast<DictionaryValue*>(root_value.get());
+ return ret &&
+ dictionary->GetBoolean(kAllowedDictionaryKey, allowed);
+}
+
+void SavePermissionToFile(
+ const GURL& origin, const FilePath& permissions_path, bool allowed) {
+#if 0
+ if (!file_util::DirectoryExists(permissions_path))
+ file_util::CreateDirectory(permissions_path);
+ // TODO(bulach): this is probably wrong! is there any utility to convert a URL
+ // to FilePath?
+ FilePath permission_file(
+ permissions_path.Append(StdStringToFilePathString(
+ GURLToCacheKey(origin))));
+ DictionaryValue dictionary;
+ dictionary.SetBoolean(kAllowedDictionaryKey, allowed);
+ std::string permission_data;
+ JSONStringValueSerializer serializer(&permission_data);
+ serializer.Serialize(dictionary);
+ file_util::WriteFile(
+ permission_file, permission_data.c_str(), permission_data.length());
+#endif // if 0
+}
+
+} // namespace
+
+GeolocationPermissionContext::GeolocationPermissionContext(
+ Profile* profile)
+ : profile_(profile),
+ is_off_the_record_(profile->IsOffTheRecord()),
+ permissions_path_(profile->GetPath().Append(FilePath(
+ kGeolocationPermissionPath))) {
+}
+
+GeolocationPermissionContext::~GeolocationPermissionContext() {
+}
+
+void GeolocationPermissionContext::RequestGeolocationPermission(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ std::map<std::string, bool>::const_iterator permission =
+ permissions_.find(GURLToCacheKey(origin));
+ if (permission != permissions_.end()) {
+ NotifyPermissionSet(
+ render_process_id, render_view_id, bridge_id, permission->second);
+ } else {
+ HandlePermissionMemoryCacheMiss(
+ render_process_id, render_view_id, bridge_id, origin);
+ }
+}
+
+void GeolocationPermissionContext::SetPermission(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin, bool allowed) {
+ SetPermissionMemoryCacheOnIOThread(origin, allowed);
+ SetPermissionOnFileThread(origin, allowed);
+ NotifyPermissionSet(render_process_id, render_view_id, bridge_id, allowed);
+}
+
+void GeolocationPermissionContext::HandlePermissionMemoryCacheMiss(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::FILE)) {
+ ChromeThread::PostTask(
+ ChromeThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &GeolocationPermissionContext::HandlePermissionMemoryCacheMiss,
+ render_process_id, render_view_id, bridge_id, origin));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+ // TODO(bulach): should we save a file per origin or have some smarter
+ // storage? Use HostContentSettingsMap instead.
+ bool allowed;
+ if (is_off_the_record_ ||
+ !ReadPermissionFromFile(origin, permissions_path_, &allowed)) {
+ RequestPermissionFromUI(
+ render_process_id, render_view_id, bridge_id, origin);
+ } else {
+ SetPermissionMemoryCacheOnIOThread(origin, allowed);
+ NotifyPermissionSet(render_process_id, render_view_id, bridge_id, allowed);
+ }
+}
+
+void GeolocationPermissionContext::RequestPermissionFromUI(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationPermissionContext::RequestPermissionFromUI,
+ render_process_id, render_view_id, bridge_id, origin));
+ return;
+ }
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
+ for (int i = 0; i < browser->tab_count(); ++i) {
+ TabContents* tab_contents = browser->GetTabContentsAt(i);
+ RenderViewHost* render_view_host = tab_contents->render_view_host();
+ if (render_view_host->process()->id() == render_process_id &&
+ render_view_host->routing_id() == render_view_id &&
+ tab_contents->GetURL().GetOrigin() == origin) {
+ tab_contents->AddInfoBar(
+ new GeolocationConfirmInfoBarDelegate(
+ tab_contents, this, render_process_id, render_view_id,
+ bridge_id, origin));
+ break;
+ }
+ }
+}
+
+void GeolocationPermissionContext::NotifyPermissionSet(
+ int render_process_id, int render_view_id, int bridge_id, bool allowed) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationPermissionContext::NotifyPermissionSet,
+ render_process_id, render_view_id, bridge_id, allowed));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ CallRenderViewHost(
+ render_process_id, render_view_id,
+ &RenderViewHost::Send,
+ new ViewMsg_Geolocation_PermissionSet(
+ render_view_id, bridge_id, allowed));
+}
+
+void GeolocationPermissionContext::SetPermissionMemoryCacheOnIOThread(
+ const GURL& origin, bool allowed) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &GeolocationPermissionContext::SetPermissionMemoryCacheOnIOThread,
+ origin, allowed));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ permissions_[GURLToCacheKey(origin)] = allowed;
+}
+
+void GeolocationPermissionContext::SetPermissionOnFileThread(
+ const GURL& origin, bool allowed) {
+ if (is_off_the_record_)
+ return;
+ if (!ChromeThread::CurrentlyOn(ChromeThread::FILE)) {
+ ChromeThread::PostTask(
+ ChromeThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this, &GeolocationPermissionContext::SetPermissionOnFileThread,
+ origin, allowed));
+ return;
+ }
+
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+
+ // TODO(bulach): should we save a file per origin or have some smarter
+ // storage? Use HostContentSettingsMap instead.
+#if 0
+ SavePermissionToFile(origin, permissions_path_, allowed);
+#endif
+}
diff --git a/chrome/browser/geolocation/geolocation_permission_context.h b/chrome/browser/geolocation/geolocation_permission_context.h
new file mode 100644
index 0000000..c859648
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_permission_context.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 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 CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
+#define CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
+
+#include <map>
+#include "base/basictypes.h"
+#include "base/file_path.h"
+#include "base/ref_counted.h"
+
+class GeolocationDispatcherHost;
+class GURL;
+class Profile;
+class RenderViewHost;
+
+// GeolocationPermissionContext manages Geolocation permissions per origin.
+// It keeps an in-memory cache of permissions, and if not available, loads
+// from disk. If there's no data, it'll trigger the UI elements to ask the
+// user for permission.
+// Regardless of where the permission data came from, it always notifies the
+// requesting render_view asynchronously via ViewMsg_Geolocation_PermissionSet.
+class GeolocationPermissionContext
+ : public base::RefCountedThreadSafe<GeolocationPermissionContext> {
+ public:
+ explicit GeolocationPermissionContext(Profile* profile);
+
+ // The render is requesting permission to use Geolocation.
+ // Response will be sent asynchronously as ViewMsg_Geolocation_PermissionSet.
+ // Must be called from the IO thread.
+ void RequestGeolocationPermission(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin);
+
+ // Called once the user sets the geolocation permission.
+ // It'll update the internal state on different threads via
+ // SetPermissionMemoryCacheOnIOThread and SetPermissionOnFileThread.
+ void SetPermission(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin, bool allowed);
+
+ private:
+ friend class base::RefCountedThreadSafe<GeolocationPermissionContext>;
+ ~GeolocationPermissionContext();
+
+ // This is initially called on the IO thread by the public API
+ // RequestGeolocationPermission when there's no data available in the
+ // in-memory cache.
+ // It forwards a call to the FILE thread which tries to load permission data
+ // from disk:
+ // - If available, it will call SetPermissionMemoryCacheOnIOThread() to write
+ // the in-memory cache in the IO thread, and NotifyPermissionSet to send the
+ // message to the corresponding render.
+ // - If not available, it'll delegate to RequestPermissionDataFromUI.
+ void HandlePermissionMemoryCacheMiss(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin);
+
+ // Triggers the associated UI element to request permission.
+ void RequestPermissionFromUI(
+ int render_process_id, int render_view_id, int bridge_id,
+ const GURL& origin);
+
+ // Notifies whether or not the corresponding render is allowed to use
+ // geolocation.
+ void NotifyPermissionSet(
+ int render_process_id, int render_view_id, int bridge_id,
+ bool allowed);
+
+ // Sets permissions_ cache (if not on IO thread, will forward to it).
+ void SetPermissionMemoryCacheOnIOThread(const GURL& origin, bool allowed);
+ // Sets permissions file data (if not on FILE thread, will forward to it).
+ void SetPermissionOnFileThread(const GURL& origin, bool allowed);
+
+ // This should only be accessed from the UI thread.
+ Profile* const profile_;
+ // Indicates whether profile_ is off the record.
+ bool const is_off_the_record_;
+ // The path where geolocation permission data is stored.
+ FilePath const permissions_path_;
+ // This should only be accessed from the UI thread.
+ std::map<std::string, bool> permissions_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeolocationPermissionContext);
+};
+
+#endif // CHROME_BROWSER_GEOLOCATION_GEOLOCATION_PERMISSION_CONTEXT_H_
diff --git a/chrome/browser/geolocation/location_arbitrator.cc b/chrome/browser/geolocation/location_arbitrator.cc
index 0b5fc0af..c82fb1d 100644
--- a/chrome/browser/geolocation/location_arbitrator.cc
+++ b/chrome/browser/geolocation/location_arbitrator.cc
@@ -13,8 +13,8 @@
#include "base/string_util.h"
#include "chrome/browser/net/url_request_context_getter.h"
#include "chrome/browser/geolocation/access_token_store.h"
-#include "chrome/browser/geolocation/geoposition.h"
#include "chrome/browser/geolocation/location_provider.h"
+#include "chrome/common/geoposition.h"
#include "googleurl/src/gurl.h"
namespace {
@@ -109,7 +109,7 @@ void GeolocationArbitratorImpl::LocationUpdateAvailable(
LocationProviderBase* provider) {
DCHECK(CalledOnValidThread());
DCHECK(provider);
- Position position;
+ Geoposition position;
provider->GetPosition(&position);
// TODO(joth): Arbitrate.
for (DelegateMap::const_iterator it = observers_.begin();
diff --git a/chrome/browser/geolocation/location_arbitrator.h b/chrome/browser/geolocation/location_arbitrator.h
index aaf61a0..b0c10bc9 100644
--- a/chrome/browser/geolocation/location_arbitrator.h
+++ b/chrome/browser/geolocation/location_arbitrator.h
@@ -7,7 +7,7 @@
class AccessTokenStoreFactory;
class URLRequestContextGetter;
-struct Position;
+struct Geoposition;
// This is the main API to the geolocaiton subsystem. Typically the application
// will hold a single instance of this class, and can register multiple
@@ -29,7 +29,7 @@ class GeolocationArbitrator {
// This will be called whenever the 'best available' location is updated,
// or when an error is encountered meaning no location data will be
// available in the forseeable future.
- virtual void OnLocationUpdate(const Position& position) = 0;
+ virtual void OnLocationUpdate(const Geoposition& position) = 0;
protected:
virtual ~Delegate() {}
diff --git a/chrome/browser/geolocation/location_arbitrator_unittest.cc b/chrome/browser/geolocation/location_arbitrator_unittest.cc
index 6e0c1d8..8d162f3 100644
--- a/chrome/browser/geolocation/location_arbitrator_unittest.cc
+++ b/chrome/browser/geolocation/location_arbitrator_unittest.cc
@@ -6,8 +6,8 @@
#include "base/scoped_ptr.h"
#include "chrome/browser/geolocation/fake_access_token_store.h"
-#include "chrome/browser/geolocation/geoposition.h"
#include "chrome/browser/geolocation/location_provider.h"
+#include "chrome/common/geoposition.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -31,11 +31,11 @@ class MockLocationProvider : public LocationProviderBase {
++started_count_;
return true;
}
- virtual void GetPosition(Position *position) {
+ virtual void GetPosition(Geoposition *position) {
*position = position_;
}
- Position position_;
+ Geoposition position_;
int started_count_;
static MockLocationProvider* instance_;
@@ -49,18 +49,18 @@ class MockLocationObserver : public GeolocationArbitrator::Delegate {
public:
void InvalidateLastPosition() {
last_position_.accuracy = -1;
- last_position_.error_code = Position::ERROR_CODE_NONE;
+ last_position_.error_code = Geoposition::ERROR_CODE_NONE;
ASSERT_FALSE(last_position_.IsInitialized());
}
// Delegate
- virtual void OnLocationUpdate(const Position& position) {
+ virtual void OnLocationUpdate(const Geoposition& position) {
last_position_ = position;
}
- Position last_position_;
+ Geoposition last_position_;
};
-void SetReferencePosition(Position* position) {
+void SetReferencePosition(Geoposition* position) {
position->latitude = 51.0;
position->longitude = -0.1;
position->accuracy = 400;
diff --git a/chrome/browser/geolocation/location_provider.h b/chrome/browser/geolocation/location_provider.h
index 8ff4acd..fbb49ad 100644
--- a/chrome/browser/geolocation/location_provider.h
+++ b/chrome/browser/geolocation/location_provider.h
@@ -20,6 +20,7 @@
class AccessTokenStore;
class GURL;
class URLRequestContextGetter;
+struct Geoposition;
struct Position;
// The base class used by all location providers.
@@ -64,7 +65,7 @@ class LocationProviderBase : public NonThreadSafe {
// Returns false if the provider failed to start.
virtual bool StartProvider() = 0;
// Gets the current best position estimate.
- virtual void GetPosition(Position* position) = 0;
+ virtual void GetPosition(Geoposition* position) = 0;
// Provides a hint to the provider that new location data is needed as soon
// as possible. Default implementation does nothing.
virtual void UpdatePosition() {}
diff --git a/chrome/browser/geolocation/network_location_provider.cc b/chrome/browser/geolocation/network_location_provider.cc
index 8d0c69e..1b05018 100644
--- a/chrome/browser/geolocation/network_location_provider.cc
+++ b/chrome/browser/geolocation/network_location_provider.cc
@@ -32,7 +32,7 @@ class NetworkLocationProvider::PositionCache {
// WiFi data. Returns true on success, false otherwise.
bool CachePosition(const RadioData& radio_data,
const WifiData& wifi_data,
- const Position& position) {
+ const Geoposition& position) {
// Check that we can generate a valid key for the device data.
string16 key;
if (!MakeKey(radio_data, wifi_data, &key)) {
@@ -57,8 +57,8 @@ class NetworkLocationProvider::PositionCache {
// Searches for a cached position response for the current set of cell ID and
// WiFi data. Returns the cached position if available, NULL otherwise.
- const Position *FindPosition(const RadioData &radio_data,
- const WifiData &wifi_data) {
+ const Geoposition *FindPosition(const RadioData &radio_data,
+ const WifiData &wifi_data) {
string16 key;
if (!MakeKey(radio_data, wifi_data, &key)) {
return NULL;
@@ -96,7 +96,7 @@ class NetworkLocationProvider::PositionCache {
// The cache of positions. This is stored using two maps. One map is keyed on
// a string that represents a set of device data, the other is keyed on the
// timestamp of the position.
- typedef std::map<string16, Position> CacheMap;
+ typedef std::map<string16, Geoposition> CacheMap;
CacheMap cache_;
typedef std::map<int64, CacheMap::iterator> CacheTimesMap;
CacheTimesMap cache_times_;
@@ -141,7 +141,7 @@ NetworkLocationProvider::~NetworkLocationProvider() {
}
// LocationProviderBase implementation
-void NetworkLocationProvider::GetPosition(Position *position) {
+void NetworkLocationProvider::GetPosition(Geoposition *position) {
DCHECK(position);
AutoLock lock(position_mutex_);
*position = position_;
@@ -176,7 +176,7 @@ void NetworkLocationProvider::DeviceDataUpdateAvailable(
// NetworkLocationRequest::ListenerInterface implementation.
void NetworkLocationProvider::LocationResponseAvailable(
- const Position& position,
+ const Geoposition& position,
bool server_error,
const string16& access_token) {
DCHECK(CalledOnValidThread());
@@ -238,7 +238,7 @@ void NetworkLocationProvider::RequestPosition() {
DCHECK(CalledOnValidThread());
delayed_start_task_.RevokeAll();
- const Position* cached_position;
+ const Geoposition* cached_position;
{
AutoLock lock(data_mutex_);
cached_position = position_cache_->FindPosition(radio_data_, wifi_data_);
diff --git a/chrome/browser/geolocation/network_location_provider.h b/chrome/browser/geolocation/network_location_provider.h
index 9dfe59ac..2988841 100644
--- a/chrome/browser/geolocation/network_location_provider.h
+++ b/chrome/browser/geolocation/network_location_provider.h
@@ -12,9 +12,9 @@
#include "base/string16.h"
#include "base/thread.h"
#include "chrome/browser/geolocation/device_data_provider.h"
-#include "chrome/browser/geolocation/geoposition.h"
#include "chrome/browser/geolocation/location_provider.h"
#include "chrome/browser/geolocation/network_location_request.h"
+#include "chrome/common/geoposition.h"
class URLFetcherProtectEntry;
@@ -32,7 +32,7 @@ class NetworkLocationProvider
// LocationProviderBase implementation
virtual bool StartProvider();
- virtual void GetPosition(Position *position);
+ virtual void GetPosition(Geoposition *position);
virtual void UpdatePosition();
private:
@@ -50,7 +50,7 @@ class NetworkLocationProvider
virtual void DeviceDataUpdateAvailable(WifiDataProvider* provider);
// NetworkLocationRequest::ListenerInterface implementation.
- virtual void LocationResponseAvailable(const Position& position,
+ virtual void LocationResponseAvailable(const Geoposition& position,
bool server_error,
const string16& access_token);
@@ -74,7 +74,7 @@ class NetworkLocationProvider
string16 access_token_;
// The current best position estimate and its guarding mutex
- Position position_;
+ Geoposition position_;
Lock position_mutex_;
bool is_new_data_available_;
diff --git a/chrome/browser/geolocation/network_location_provider_unittest.cc b/chrome/browser/geolocation/network_location_provider_unittest.cc
index f8af128..34e6b2d 100644
--- a/chrome/browser/geolocation/network_location_provider_unittest.cc
+++ b/chrome/browser/geolocation/network_location_provider_unittest.cc
@@ -298,7 +298,7 @@ TEST_F(GeolocationNetworkProviderTest, MultipleWifiScansComplete) {
EXPECT_TRUE(access_token_store_->GetAccessToken(&token));
EXPECT_EQ(REFERENCE_ACCESS_TOKEN, UTF16ToUTF8(token));
- Position position;
+ Geoposition position;
provider->GetPosition(&position);
EXPECT_FALSE(position.IsValidFix());
diff --git a/chrome/browser/geolocation/network_location_request.cc b/chrome/browser/geolocation/network_location_request.cc
index 65e3f37..ecf41d9 100644
--- a/chrome/browser/geolocation/network_location_request.cc
+++ b/chrome/browser/geolocation/network_location_request.cc
@@ -8,8 +8,8 @@
#include "base/json/json_writer.h"
#include "base/string_util.h"
#include "base/values.h"
-#include "chrome/browser/geolocation/geoposition.h"
#include "chrome/browser/net/url_request_context_getter.h"
+#include "chrome/common/geoposition.h"
#include "net/url_request/url_request_status.h"
namespace {
@@ -39,7 +39,7 @@ void GetLocationFromResponse(bool http_post_result,
const std::string& response_body,
int64 timestamp,
const GURL& server_url,
- Position* position,
+ Geoposition* position,
string16* access_token);
const char* RadioTypeToString(RadioType type);
@@ -54,7 +54,7 @@ void AddInteger(const std::wstring& property_name,
// Parses the server response body. Returns true if parsing was successful.
bool ParseServerResponse(const std::string& response_body,
int64 timestamp,
- Position* position,
+ Geoposition* position,
string16* access_token);
void AddRadioData(const RadioData& radio_data, DictionaryValue* body_object);
void AddWifiData(const WifiData& wifi_data, DictionaryValue* body_object);
@@ -105,7 +105,7 @@ void NetworkLocationRequest::OnURLFetchComplete(const URLFetcher* source,
DCHECK_EQ(url_fetcher_.get(), source);
DCHECK(url_.possibly_invalid_spec() == url.possibly_invalid_spec());
- Position position;
+ Geoposition position;
string16 access_token;
GetLocationFromResponse(status.is_success(), response_code, data,
timestamp_, url, &position, &access_token);
@@ -162,8 +162,8 @@ bool FormRequestBody(const string16& host_name,
void FormatPositionError(const GURL& server_url,
const std::wstring& message,
- Position* position) {
- position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
+ Geoposition* position) {
+ position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
position->error_message = L"Network location provider at '";
position->error_message += ASCIIToWide(server_url.possibly_invalid_spec());
position->error_message += L"' : ";
@@ -178,7 +178,7 @@ void GetLocationFromResponse(bool http_post_result,
const std::string& response_body,
int64 timestamp,
const GURL& server_url,
- Position* position,
+ Geoposition* position,
string16* access_token) {
DCHECK(position);
DCHECK(access_token);
@@ -268,7 +268,7 @@ bool GetAsDouble(const DictionaryValue& object,
bool ParseServerResponse(const std::string& response_body,
int64 timestamp,
- Position* position,
+ Geoposition* position,
string16* access_token) {
DCHECK(position);
DCHECK(access_token);
diff --git a/chrome/browser/geolocation/network_location_request.h b/chrome/browser/geolocation/network_location_request.h
index da89cb1..97cf16c 100644
--- a/chrome/browser/geolocation/network_location_request.h
+++ b/chrome/browser/geolocation/network_location_request.h
@@ -14,6 +14,7 @@
class URLRequestContextGetter;
class URLFetcher;
+struct Geoposition;
struct Position;
// Takes a set of device data and sends it to a server to get a position fix.
@@ -26,7 +27,7 @@ class NetworkLocationRequest : private URLFetcher::Delegate {
// Updates the listener with a new position. server_error indicates whether
// was a server or network error - either no response or a 500 error code.
virtual void LocationResponseAvailable(
- const Position& position,
+ const Geoposition& position,
bool server_error,
const string16& access_token) = 0;