diff options
author | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-18 16:44:22 +0000 |
---|---|---|
committer | bulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-18 16:44:22 +0000 |
commit | 434afdcf94e2319ff03872db312d489a44637508 (patch) | |
tree | 3414ee5da70cb7ada1074c36cfc001e4ebfd5438 /chrome/browser/geolocation | |
parent | f01e0a37fa8f328b8694c9abc69ecc62fbc9690a (diff) | |
download | chromium_src-434afdcf94e2319ff03872db312d489a44637508.zip chromium_src-434afdcf94e2319ff03872db312d489a44637508.tar.gz chromium_src-434afdcf94e2319ff03872db312d489a44637508.tar.bz2 |
Initial Geolocation implementation
Adds IPC plumbing.
Adds Infobar buttons for requesting permission
TEST=geolocation_browsertest.cc
Review URL: http://codereview.chromium.org/548188
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39366 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/geolocation')
16 files changed, 893 insertions, 145 deletions
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc new file mode 100644 index 0000000..40c7bd9 --- /dev/null +++ b/chrome/browser/geolocation/geolocation_browsertest.cc @@ -0,0 +1,248 @@ +// Copyright (c) 2009 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 "base/string_util.h" +#include "chrome/browser/app_modal_dialog.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/geoposition.h" +#include "chrome/common/notification_details.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/render_messages.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" +#include "net/base/net_util.h" + +// This is a browser test for Geolocation. +// It exercises various integration points from javascript <-> browser: +// 1. Infobar is displayed when a geolocation is requested from an unauthorized +// origin. +// 2. Denying the infobar triggers the correct error callback. +// 3. Allowing the infobar does not trigger an error, and allow a geoposition to +// be passed to javascript. +// 4. Permissions persisted in disk are respected. +// 5. Off the record profiles don't use saved permissions. +class GeolocationBrowserTest + : public InProcessBrowserTest, public NotificationObserver { + public: + GeolocationBrowserTest() : infobar_(NULL), current_browser_(NULL) { + EnableDOMAutomation(); + } + + enum InitializationOptions { + INITIALIZATION_NONE, + INITIALIZATION_OFFTHERECORD, + INITIALIZATION_NEWTAB, + }; + + void Initialize(InitializationOptions options) { + if (!server_.get()) { + server_ = StartHTTPServer(); + } + GURL url = server_->TestServerPage("files/geolocation/simple.html"); + if (options == INITIALIZATION_OFFTHERECORD) { + ui_test_utils::OpenURLOffTheRecord(browser()->profile(), url); + current_browser_ = BrowserList::FindBrowserWithType( + browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL); + } else if (options == INITIALIZATION_NEWTAB) { + current_browser_ = browser(); + current_browser_->NewTab(); + ui_test_utils::NavigateToURL(current_browser_, url); + } else { + current_browser_ = browser(); + ui_test_utils::NavigateToURL(current_browser_, url); + } + EXPECT_TRUE(current_browser_); + + int watch_id = 0; + EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt( + current_browser_->GetSelectedTabContents()->render_view_host(), L"", + UTF8ToWide("window.domAutomationController.send(geoStart());"), + &watch_id)); + EXPECT_GT(watch_id, 0); + } + + void SendGeoposition(bool wait_for_infobar, const Geoposition& geoposition) { + if (wait_for_infobar) { + // Observe infobar notification. + registrar_.Add( + this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, + NotificationService::AllSources()); + } + + // Sending the Geoposition makes webkit trigger the permission request flow. + // If the origin is already allowed, no infobar will be displayed. + RenderViewHost* render_view_host = + current_browser_->GetSelectedTabContents()->render_view_host(); + render_view_host->Send( + new ViewMsg_Geolocation_PositionUpdated( + render_view_host->routing_id(), geoposition)); + + if (wait_for_infobar) { + ui_test_utils::RunMessageLoop(); + EXPECT_TRUE(infobar_); + registrar_.Remove(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED, + NotificationService::AllSources()); + } + } + + void WaitForJSPrompt() { + AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); + ASSERT_TRUE(alert); + alert->CloseModalDialog(); + } + + void SetInfobarResponse(bool allowed) { + registrar_.Add( + this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + NotificationService::AllSources()); + ASSERT_TRUE(infobar_); + if (allowed) + infobar_->AsConfirmInfoBarDelegate()->Accept(); + else + infobar_->AsConfirmInfoBarDelegate()->Cancel(); + current_browser_->GetSelectedTabContents()->RemoveInfoBar(infobar_); + EXPECT_FALSE(infobar_); + registrar_.Remove(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, + NotificationService::AllSources()); + } + + void CheckValueFromJavascript( + const std::string& expected, const std::string& function) { + std::string js_call = StringPrintf( + "window.domAutomationController.send(%s);", function.c_str()); + std::string value; + EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( + current_browser_->GetSelectedTabContents()->render_view_host(), L"", + UTF8ToWide(js_call), + &value)); + EXPECT_EQ(expected, value); + } + + // InProcessBrowserTest + virtual void SetUpCommandLine(CommandLine* command_line) { + InProcessBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch(switches::kEnableGeolocation); + } + + // NotificationObserver + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) { + infobar_ = Details<InfoBarDelegate>(details).ptr(); + ASSERT_TRUE(infobar_->GetIcon()); + ASSERT_TRUE(infobar_->AsConfirmInfoBarDelegate()); + MessageLoopForUI::current()->Quit(); + } else if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) { + infobar_ = NULL; + } + } + + NotificationRegistrar registrar_; + InfoBarDelegate* infobar_; + Browser* current_browser_; + scoped_refptr<HTTPTestServer> server_; +}; + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DisplaysPermissionBar) { + Initialize(INITIALIZATION_NONE); + SendGeoposition(true, Geoposition()); +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, ErrorOnPermissionDenied) { + Initialize(INITIALIZATION_NONE); + SendGeoposition(true, Geoposition()); + // Infobar was displayed, deny access and check for error code. + SetInfobarResponse(false); + WaitForJSPrompt(); + CheckValueFromJavascript("1", "geoGetLastError()"); +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForSecondTab) { +#if 0 + Initialize(INITIALIZATION_NONE); + SendGeoposition(true, Geoposition()); + SetInfobarResponse(true); + WaitForJSPrompt(); + // Checks infobar will not be created a second tab. + Initialize(INITIALIZATION_NEWTAB); + SendGeoposition(false, Geoposition()); + WaitForJSPrompt(); + CheckValueFromJavascript("0", "geoGetLastError()"); +#endif +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForDeniedOrigin) { +#if 0 + WritePermissionFile("{\"allowed\":false}"); + // Checks no infobar will be created. + Initialize(INITIALIZATION_NONE); + SendGeoposition(false, Geoposition()); + WaitForJSPrompt(); + CheckValueFromJavascript("1", "geoGetLastError()"); + // Checks infobar will not be created a second tab. + Initialize(INITIALIZATION_NEWTAB); + SendGeoposition(false, Geoposition()); + WaitForJSPrompt(); + CheckValueFromJavascript("1", "geoGetLastError()"); +#endif +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForAllowedOrigin) { +#if 0 + WritePermissionFile("{\"allowed\":true}"); + // Checks no infobar will be created and there's no error callback. + Initialize(INITIALIZATION_NONE); + SendGeoposition(false, Geoposition()); + WaitForJSPrompt(); + CheckValueFromJavascript("0", "geoGetLastError()"); +#endif +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, InfobarForOffTheRecord) { +#if 0 + // Checks infobar will be created for regular profile. + Initialize(INITIALIZATION_NONE); + SendGeoposition(true, Geoposition()); + SetInfobarResponse(true); + WaitForJSPrompt(); + CheckValueFromJavascript("0", "geoGetLastError()"); + // Go off the record, and checks infobar will be created and an error callback + // is triggered. + Initialize(INITIALIZATION_OFFTHERECORD); + SendGeoposition(true, Geoposition()); + SetInfobarResponse(false); + WaitForJSPrompt(); + CheckValueFromJavascript("1", "geoGetLastError()"); +#endif +} + +IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, Geoposition) { + // Checks infobar will be created. + Initialize(INITIALIZATION_NONE); + SendGeoposition(true, Geoposition()); + // Infobar was displayed, allow access and check there's no error code. + SetInfobarResponse(true); + WaitForJSPrompt(); + CheckValueFromJavascript("0", "geoGetLastError()"); + // Sends a Geoposition over IPC, and check it arrives in the javascript side. + Geoposition geoposition; + geoposition.latitude = 3.17; + geoposition.longitude = 4.23; + SendGeoposition(false, geoposition); + WaitForJSPrompt(); + // Checks we have no error. + CheckValueFromJavascript("0", "geoGetLastError()"); + CheckValueFromJavascript( + DoubleToString(geoposition.latitude), "geoGetLastPositionLatitude()"); + CheckValueFromJavascript( + DoubleToString(geoposition.longitude), "geoGetLastPositionLongitude()"); +} 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/geoposition.cc b/chrome/browser/geolocation/geoposition.cc deleted file mode 100644 index 8618431..0000000 --- a/chrome/browser/geolocation/geoposition.cc +++ /dev/null @@ -1,55 +0,0 @@ -// 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/geoposition.h" - -namespace { -// Sentinel values to mark invalid data. (WebKit carries companion is_valid -// bools for this purpose; we may eventually follow that approach, but -// sentinels worked OK in the gears code this is based on.) -const double kBadLatLng = 200; -// Lowest point on land is at approximately -400 metres. -const int kBadAltitude = -1000; -const int kBadAccuracy = -1; // Accuracy must be non-negative. -const int64 kBadTimestamp = kint64min; -} - -Position::Position() - : latitude(kBadLatLng), - longitude(kBadLatLng), - altitude(kBadAltitude), - accuracy(kBadAccuracy), - altitude_accuracy(kBadAccuracy), - timestamp(kBadTimestamp), - error_code(ERROR_CODE_NONE) { -} - -bool Position::is_valid_latlong() const { - return latitude >= -90.0 && latitude <= 90.0 && - longitude >= -180.0 && longitude <= 180.0; -} - -bool Position::is_valid_altitude() const { - return altitude > kBadAltitude; -} - -bool Position::is_valid_accuracy() const { - return accuracy >= 0.0; -} - -bool Position::is_valid_altitude_accuracy() const { - return altitude_accuracy >= 0.0; -} - -bool Position::is_valid_timestamp() const { - return timestamp != kBadTimestamp; -} - -bool Position::IsValidFix() const { - return is_valid_latlong() && is_valid_accuracy() && is_valid_timestamp(); -} - -bool Position::IsInitialized() const { - return error_code != ERROR_CODE_NONE || IsValidFix(); -} diff --git a/chrome/browser/geolocation/geoposition.h b/chrome/browser/geolocation/geoposition.h deleted file mode 100644 index 7143638..0000000 --- a/chrome/browser/geolocation/geoposition.h +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -// This file declares the Position structure, which is used to represent a -// position fix. Originally derived from -// http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation.h - -#ifndef CHROME_BROWSER_GEOLOCATION_GEOPOSITION_H_ -#define CHROME_BROWSER_GEOLOCATION_GEOPOSITION_H_ - -#include "base/string16.h" - -// The internal representation of a position. Some properties use different -// types when passed to JavaScript. -struct Position { - public: - // Error codes for returning to JavaScript. These values are defined by the - // W3C spec. Note that Gears does not use all of these codes, but we need - // values for all of them to allow us to provide the constants on the error - // object. - enum ErrorCode { - ERROR_CODE_NONE = 0, // Chrome addition - ERROR_CODE_PERMISSION_DENIED = 1, - ERROR_CODE_POSITION_UNAVAILABLE = 2, - ERROR_CODE_TIMEOUT = 3, - }; - - Position(); - - bool is_valid_latlong() const; - bool is_valid_altitude() const; - bool is_valid_accuracy() const; - bool is_valid_altitude_accuracy() const; - bool is_valid_timestamp() const; - - // A valid fix has a valid latitude, longitude, accuracy and timestamp. - bool IsValidFix() const; - - // A position is considered initialized if it has either a valid fix or - // an error code other than NONE. - bool IsInitialized() const; - - // These properties correspond to the JavaScript Position object. - double latitude; // In degrees - double longitude; // In degrees - double altitude; // In metres - double accuracy; // In metres - double altitude_accuracy; // In metres - int64 timestamp; // Milliseconds since 1st Jan 1970 - - // These properties are returned to JavaScript as a PositionError object. - ErrorCode error_code; - std::wstring error_message; // Human-readable error message -}; - -#endif // CHROME_BROWSER_GEOLOCATION_GEOPOSITION_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; |