summaryrefslogtreecommitdiffstats
path: root/chromeos
diff options
context:
space:
mode:
authoralemate <alemate@chromium.org>2016-03-23 16:21:44 -0700
committerCommit bot <commit-bot@chromium.org>2016-03-23 23:23:11 +0000
commit9af1adea25a1a643a7f849616d3f51b33a9657aa (patch)
tree256c9b65f55eac24bada6ebfbb14ef041645801c /chromeos
parent0970ff860aba75cc0b35d58e6b6133291653ac56 (diff)
downloadchromium_src-9af1adea25a1a643a7f849616d3f51b33a9657aa.zip
chromium_src-9af1adea25a1a643a7f849616d3f51b33a9657aa.tar.gz
chromium_src-9af1adea25a1a643a7f849616d3f51b33a9657aa.tar.bz2
SimpleGeolocation should support sending WiFi AP data.
BUG=596690 TEST=unittest Review URL: https://codereview.chromium.org/1819173002 Cr-Commit-Position: refs/heads/master@{#382968}
Diffstat (limited to 'chromeos')
-rw-r--r--chromeos/BUILD.gn2
-rw-r--r--chromeos/chromeos.gyp2
-rw-r--r--chromeos/geolocation/simple_geolocation_provider.cc23
-rw-r--r--chromeos/geolocation/simple_geolocation_provider.h6
-rw-r--r--chromeos/geolocation/simple_geolocation_request.cc98
-rw-r--r--chromeos/geolocation/simple_geolocation_request.h23
-rw-r--r--chromeos/geolocation/simple_geolocation_request_test_monitor.cc19
-rw-r--r--chromeos/geolocation/simple_geolocation_request_test_monitor.h31
-rw-r--r--chromeos/geolocation/simple_geolocation_unittest.cc224
-rw-r--r--chromeos/network/geolocation_handler.h2
-rw-r--r--chromeos/timezone/timezone_resolver.cc4
-rw-r--r--chromeos/timezone/timezone_resolver.h2
12 files changed, 407 insertions, 29 deletions
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index 83c04f6..fe418ee 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -93,6 +93,8 @@ static_library("test_support") {
"dbus/services/service_provider_test_helper.h",
"disks/mock_disk_mount_manager.cc",
"disks/mock_disk_mount_manager.h",
+ "geolocation/simple_geolocation_request_test_monitor.cc",
+ "geolocation/simple_geolocation_request_test_monitor.h",
"login/auth/fake_extended_authenticator.cc",
"login/auth/fake_extended_authenticator.h",
"login/auth/mock_auth_attempt_state_resolver.cc",
diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp
index 049a542..e4281e7 100644
--- a/chromeos/chromeos.gyp
+++ b/chromeos/chromeos.gyp
@@ -584,6 +584,8 @@
'dbus/services/service_provider_test_helper.h',
'disks/mock_disk_mount_manager.cc',
'disks/mock_disk_mount_manager.h',
+ 'geolocation/simple_geolocation_request_test_monitor.cc',
+ 'geolocation/simple_geolocation_request_test_monitor.h',
'login/auth/fake_extended_authenticator.cc',
'login/auth/fake_extended_authenticator.h',
'login/auth/mock_auth_attempt_state_resolver.cc',
diff --git a/chromeos/geolocation/simple_geolocation_provider.cc b/chromeos/geolocation/simple_geolocation_provider.cc
index e083b3e..0a26ede 100644
--- a/chromeos/geolocation/simple_geolocation_provider.cc
+++ b/chromeos/geolocation/simple_geolocation_provider.cc
@@ -9,6 +9,8 @@
#include "base/bind.h"
#include "chromeos/geolocation/geoposition.h"
+#include "chromeos/network/geolocation_handler.h"
+#include "chromeos/network/network_handler.h"
#include "net/url_request/url_request_context_getter.h"
namespace chromeos {
@@ -16,6 +18,20 @@ namespace chromeos {
namespace {
const char kDefaultGeolocationProviderUrl[] =
"https://www.googleapis.com/geolocation/v1/geolocate?";
+
+scoped_ptr<WifiAccessPointVector> GetAccessPointData() {
+ if (!chromeos::NetworkHandler::Get()->geolocation_handler()->wifi_enabled())
+ return nullptr;
+
+ scoped_ptr<WifiAccessPointVector> result(new chromeos::WifiAccessPointVector);
+ int64_t age_ms = 0;
+ if (!NetworkHandler::Get()->geolocation_handler()->GetWifiAccessPoints(
+ result.get(), &age_ms)) {
+ return nullptr;
+ }
+ return result;
+}
+
} // namespace
SimpleGeolocationProvider::SimpleGeolocationProvider(
@@ -30,10 +46,13 @@ SimpleGeolocationProvider::~SimpleGeolocationProvider() {
void SimpleGeolocationProvider::RequestGeolocation(
base::TimeDelta timeout,
+ bool send_wifi_access_points,
SimpleGeolocationRequest::ResponseCallback callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- SimpleGeolocationRequest* request(
- new SimpleGeolocationRequest(url_context_getter_.get(), url_, timeout));
+
+ SimpleGeolocationRequest* request(new SimpleGeolocationRequest(
+ url_context_getter_.get(), url_, timeout,
+ send_wifi_access_points ? GetAccessPointData() : nullptr));
requests_.push_back(request);
// SimpleGeolocationProvider owns all requests. It is safe to pass unretained
diff --git a/chromeos/geolocation/simple_geolocation_provider.h b/chromeos/geolocation/simple_geolocation_provider.h
index 6ba20dc..245dc27 100644
--- a/chromeos/geolocation/simple_geolocation_provider.h
+++ b/chromeos/geolocation/simple_geolocation_provider.h
@@ -33,9 +33,11 @@ class CHROMEOS_EXPORT SimpleGeolocationProvider {
const GURL& url);
virtual ~SimpleGeolocationProvider();
- // Initiates new request (See SimpleGeolocationRequest for parameters
- // description.)
+ // Initiates new request. If |send_wifi_access_points|, WiFi AP information
+ // will be added to the request. See SimpleGeolocationRequest for the
+ // description of the other parameters.
void RequestGeolocation(base::TimeDelta timeout,
+ bool send_wifi_access_points,
SimpleGeolocationRequest::ResponseCallback callback);
// Returns default geolocation service URL.
diff --git a/chromeos/geolocation/simple_geolocation_request.cc b/chromeos/geolocation/simple_geolocation_request.cc
index 01f48a0..5a27979 100644
--- a/chromeos/geolocation/simple_geolocation_request.cc
+++ b/chromeos/geolocation/simple_geolocation_request.cc
@@ -10,6 +10,7 @@
#include <string>
#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "base/strings/string_number_conversions.h"
@@ -17,6 +18,7 @@
#include "base/time/time.h"
#include "base/values.h"
#include "chromeos/geolocation/simple_geolocation_provider.h"
+#include "chromeos/geolocation/simple_geolocation_request_test_monitor.h"
#include "google_apis/google_api_keys.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
@@ -38,7 +40,18 @@ namespace chromeos {
namespace {
// The full request text. (no parameters are supported by now)
-const char kSimpleGeolocationRequestBody[] = "{\"considerIP\": \"true\"}";
+const char kSimpleGeolocationRequestBody[] = "{\"considerIp\": \"true\"}";
+
+// Request data
+const char kConsiderIp[] = "considerIp";
+const char kWifiAccessPoints[] = "wifiAccessPoints";
+
+// WiFi access point objects.
+const char kMacAddress[] = "macAddress";
+const char kSignalStrength[] = "signalStrength";
+const char kAge[] = "age";
+const char kChannel[] = "channel";
+const char kSignalToNoiseRatio[] = "signalToNoiseRatio";
// Response data.
const char kLocationString[] = "location";
@@ -88,6 +101,8 @@ enum SimpleGeolocationRequestResult {
SIMPLE_GEOLOCATION_REQUEST_RESULT_COUNT = 4
};
+SimpleGeolocationRequestTestMonitor* g_test_request_hook = nullptr;
+
// Too many requests (more than 1) mean there is a problem in implementation.
void RecordUmaEvent(SimpleGeolocationRequestEvent event) {
UMA_HISTOGRAM_ENUMERATION("SimpleGeolocation.Request.Event",
@@ -247,6 +262,9 @@ bool GetGeolocationFromResponse(bool http_success,
const std::string& response_body,
const GURL& server_url,
Geoposition* position) {
+ VLOG(1) << "GetGeolocationFromResponse(http_success=" << http_success
+ << ", status_code=" << status_code << "): response_body:\n"
+ << response_body;
// HttpPost can fail for a number of reasons. Most likely this is because
// we're offline, or there was no response.
@@ -266,12 +284,17 @@ bool GetGeolocationFromResponse(bool http_success,
return ParseServerResponse(server_url, response_body, position);
}
+void ReportUmaHasWiFiAccessPoints(bool value) {
+ UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value);
+}
+
} // namespace
SimpleGeolocationRequest::SimpleGeolocationRequest(
net::URLRequestContextGetter* url_context_getter,
const GURL& service_url,
- base::TimeDelta timeout)
+ base::TimeDelta timeout,
+ scoped_ptr<WifiAccessPointVector> wifi_data)
: url_context_getter_(url_context_getter),
service_url_(service_url),
retry_sleep_on_server_error_(base::TimeDelta::FromSeconds(
@@ -279,8 +302,8 @@ SimpleGeolocationRequest::SimpleGeolocationRequest(
retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds(
kResolveGeolocationRetrySleepBadResponseSeconds)),
timeout_(timeout),
- retries_(0) {
-}
+ retries_(0),
+ wifi_data_(wifi_data.release()) {}
SimpleGeolocationRequest::~SimpleGeolocationRequest() {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -290,6 +313,51 @@ SimpleGeolocationRequest::~SimpleGeolocationRequest() {
RecordUmaResponseTime(base::Time::Now() - request_started_at_, false);
RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_);
}
+
+ if (g_test_request_hook)
+ g_test_request_hook->OnRequestCreated(this);
+}
+
+std::string SimpleGeolocationRequest::FormatRequestBody() const {
+ if (!wifi_data_) {
+ ReportUmaHasWiFiAccessPoints(false);
+ return std::string(kSimpleGeolocationRequestBody);
+ }
+
+ scoped_ptr<base::DictionaryValue> request(new base::DictionaryValue);
+ request->SetBooleanWithoutPathExpansion(kConsiderIp, true);
+
+ base::ListValue* wifi_access_points(new base::ListValue);
+ request->SetWithoutPathExpansion(kWifiAccessPoints, wifi_access_points);
+
+ for (const WifiAccessPoint& access_point : *wifi_data_) {
+ base::DictionaryValue* access_point_dictionary = new base::DictionaryValue;
+ wifi_access_points->Append(access_point_dictionary);
+
+ access_point_dictionary->SetStringWithoutPathExpansion(
+ kMacAddress, access_point.mac_address);
+ access_point_dictionary->SetIntegerWithoutPathExpansion(
+ kSignalStrength, access_point.signal_strength);
+ if (!access_point.timestamp.is_null()) {
+ access_point_dictionary->SetStringWithoutPathExpansion(
+ kAge,
+ base::Int64ToString(
+ (base::Time::Now() - access_point.timestamp).InMilliseconds()));
+ }
+
+ access_point_dictionary->SetIntegerWithoutPathExpansion(
+ kChannel, access_point.channel);
+ access_point_dictionary->SetIntegerWithoutPathExpansion(
+ kSignalToNoiseRatio, access_point.signal_to_noise);
+ }
+ std::string result;
+ if (!base::JSONWriter::Write(*request, &result)) {
+ ReportUmaHasWiFiAccessPoints(false);
+ return std::string(kSimpleGeolocationRequestBody);
+ }
+ ReportUmaHasWiFiAccessPoints(wifi_data_->size());
+
+ return result;
}
void SimpleGeolocationRequest::StartRequest() {
@@ -297,16 +365,24 @@ void SimpleGeolocationRequest::StartRequest() {
RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START);
++retries_;
+ const std::string request_body = FormatRequestBody();
+ VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n"
+ << request_body;
+
url_fetcher_ =
net::URLFetcher::Create(request_url_, net::URLFetcher::POST, this);
url_fetcher_->SetRequestContext(url_context_getter_.get());
- url_fetcher_->SetUploadData("application/json",
- std::string(kSimpleGeolocationRequestBody));
+ url_fetcher_->SetUploadData("application/json", request_body);
url_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE |
net::LOAD_DISABLE_CACHE |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA);
+
+ // Call test hook before asynchronous request actually starts.
+ if (g_test_request_hook)
+ g_test_request_hook->OnStart(this);
+
url_fetcher_->Start();
}
@@ -319,6 +395,16 @@ void SimpleGeolocationRequest::MakeRequest(const ResponseCallback& callback) {
StartRequest();
}
+// static
+void SimpleGeolocationRequest::SetTestMonitor(
+ SimpleGeolocationRequestTestMonitor* monitor) {
+ g_test_request_hook = monitor;
+}
+
+std::string SimpleGeolocationRequest::FormatRequestBodyForTesting() const {
+ return FormatRequestBody();
+}
+
void SimpleGeolocationRequest::Retry(bool server_error) {
base::TimeDelta delay(server_error ? retry_sleep_on_server_error_
: retry_sleep_on_bad_response_);
diff --git a/chromeos/geolocation/simple_geolocation_request.h b/chromeos/geolocation/simple_geolocation_request.h
index 8771e5d..19ff507 100644
--- a/chromeos/geolocation/simple_geolocation_request.h
+++ b/chromeos/geolocation/simple_geolocation_request.h
@@ -12,7 +12,9 @@
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
+#include "chromeos/chromeos_export.h"
#include "chromeos/geolocation/geoposition.h"
+#include "chromeos/network/network_util.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h"
@@ -23,6 +25,8 @@ class URLRequestContextGetter;
namespace chromeos {
+class SimpleGeolocationRequestTestMonitor;
+
// Sends request to a server to get local geolocation information.
// It performs formatting of the request and interpretation of the response.
// Request is owned and destroyed by caller (usually SimpleGeolocationProvider).
@@ -32,7 +36,10 @@ namespace chromeos {
// (position.status is set to STATUS_TIMEOUT.)
// - If request is destroyed while callback has not beed called yet, request
// is silently cancelled.
-class SimpleGeolocationRequest : private net::URLFetcherDelegate {
+//
+// Note: we need CHROMEOS_EXPORT for tests.
+class CHROMEOS_EXPORT SimpleGeolocationRequest
+ : private net::URLFetcherDelegate {
public:
// Called when a new geo geolocation information is available.
// The second argument indicates whether there was a server error or not.
@@ -44,9 +51,11 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
// |url| is the server address to which the request wil be sent.
// |timeout| retry request on error until timeout.
+ // If wifi_data is not null, it will be sent to the geolocation server.
SimpleGeolocationRequest(net::URLRequestContextGetter* url_context_getter,
const GURL& service_url,
- base::TimeDelta timeout);
+ base::TimeDelta timeout,
+ scoped_ptr<WifiAccessPointVector> wifi_data);
~SimpleGeolocationRequest() override;
@@ -65,6 +74,11 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
retry_sleep_on_bad_response_ = value;
}
+ // Sets global requests monitoring object for testing.
+ static void SetTestMonitor(SimpleGeolocationRequestTestMonitor* monitor);
+
+ std::string FormatRequestBodyForTesting() const;
+
private:
// net::URLFetcherDelegate
void OnURLFetchComplete(const net::URLFetcher* source) override;
@@ -81,6 +95,9 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
// Called by timeout_timer_ .
void OnTimeout();
+ // Returns API request body.
+ std::string FormatRequestBody() const;
+
scoped_refptr<net::URLRequestContextGetter> url_context_getter_;
// Service URL from constructor arguments.
@@ -114,6 +131,8 @@ class SimpleGeolocationRequest : private net::URLFetcherDelegate {
// This is updated on each retry.
Geoposition position_;
+ scoped_ptr<WifiAccessPointVector> wifi_data_;
+
// Creation and destruction should happen on the same thread.
base::ThreadChecker thread_checker_;
diff --git a/chromeos/geolocation/simple_geolocation_request_test_monitor.cc b/chromeos/geolocation/simple_geolocation_request_test_monitor.cc
new file mode 100644
index 0000000..d303b8c
--- /dev/null
+++ b/chromeos/geolocation/simple_geolocation_request_test_monitor.cc
@@ -0,0 +1,19 @@
+// Copyright 2016 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 "chromeos/geolocation/simple_geolocation_request_test_monitor.h"
+
+namespace chromeos {
+
+SimpleGeolocationRequestTestMonitor::SimpleGeolocationRequestTestMonitor() {}
+
+SimpleGeolocationRequestTestMonitor::~SimpleGeolocationRequestTestMonitor() {}
+
+void SimpleGeolocationRequestTestMonitor::OnRequestCreated(
+ SimpleGeolocationRequest* request) {}
+
+void SimpleGeolocationRequestTestMonitor::OnStart(
+ SimpleGeolocationRequest* request) {}
+
+} // namespace chromeos
diff --git a/chromeos/geolocation/simple_geolocation_request_test_monitor.h b/chromeos/geolocation/simple_geolocation_request_test_monitor.h
new file mode 100644
index 0000000..2213db2
--- /dev/null
+++ b/chromeos/geolocation/simple_geolocation_request_test_monitor.h
@@ -0,0 +1,31 @@
+// Copyright 2016 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 CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_TEST_MONITOR_H_
+#define CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_TEST_MONITOR_H_
+
+#include "base/macros.h"
+
+namespace chromeos {
+
+class SimpleGeolocationRequest;
+
+// This is global hook, that allows to monitor SimpleGeolocationRequest
+// in tests.
+
+class SimpleGeolocationRequestTestMonitor {
+ public:
+ SimpleGeolocationRequestTestMonitor();
+
+ virtual ~SimpleGeolocationRequestTestMonitor();
+ virtual void OnRequestCreated(SimpleGeolocationRequest* request);
+ virtual void OnStart(SimpleGeolocationRequest* request);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleGeolocationRequestTestMonitor);
+};
+
+} // namespace chromeos
+
+#endif // CHROMEOS_GEOLOCATION_SIMPLE_GEOLOCATION_REQUEST_TEST_MONITOR_H_
diff --git a/chromeos/geolocation/simple_geolocation_unittest.cc b/chromeos/geolocation/simple_geolocation_unittest.cc
index 6c8fb42..61c83b9 100644
--- a/chromeos/geolocation/simple_geolocation_unittest.cc
+++ b/chromeos/geolocation/simple_geolocation_unittest.cc
@@ -7,13 +7,21 @@
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/geolocation/simple_geolocation_provider.h"
+#include "chromeos/geolocation/simple_geolocation_request_test_monitor.h"
+#include "chromeos/network/geolocation_handler.h"
+#include "chromeos/network/network_handler.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_impl.h"
#include "net/url_request/url_request_status.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
namespace {
@@ -32,6 +40,24 @@ const char kSimpleResponseBody[] =
" },\n"
" \"accuracy\": 1200.4\n"
"}";
+const char kIPOnlyRequestBody[] = "{\"considerIp\": \"true\"}";
+const char kOneWiFiAPRequestBody[] =
+ "{"
+ "\"considerIp\":true,"
+ "\"wifiAccessPoints\":["
+ "{"
+ "\"channel\":1,"
+ "\"macAddress\":\"01:00:00:00:00:00\","
+ "\"signalStrength\":10,"
+ "\"signalToNoiseRatio\":0"
+ "}"
+ "]"
+ "}";
+const char kExpectedPosition[] =
+ "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
+ "error_code=0, error_message='', status=1 (OK)";
+
+const char kWiFiAP1MacAddress[] = "01:00:00:00:00:00";
} // anonymous namespace
namespace chromeos {
@@ -46,7 +72,7 @@ class TestGeolocationAPIURLFetcherCallback {
: url_(url),
require_retries_(require_retries),
response_(response),
- factory_(NULL),
+ factory_(nullptr),
attempts_(0),
provider_(provider) {}
@@ -115,9 +141,9 @@ class GeolocationAPIFetcherFactory {
SimpleGeolocationProvider* provider) {
url_callback_.reset(new TestGeolocationAPIURLFetcherCallback(
url, require_retries, response, provider));
- net::URLFetcherImpl::set_factory(NULL);
+ net::URLFetcherImpl::set_factory(nullptr);
fetcher_factory_.reset(new net::FakeURLFetcherFactory(
- NULL,
+ nullptr,
base::Bind(&TestGeolocationAPIURLFetcherCallback::CreateURLFetcher,
base::Unretained(url_callback_.get()))));
url_callback_->Initialize(fetcher_factory_.get());
@@ -162,13 +188,31 @@ class GeolocationReceiver {
scoped_ptr<base::RunLoop> message_loop_runner_;
};
+class WiFiTestMonitor : public SimpleGeolocationRequestTestMonitor {
+ public:
+ WiFiTestMonitor() {}
+
+ void OnRequestCreated(SimpleGeolocationRequest* request) override {}
+ void OnStart(SimpleGeolocationRequest* request) override {
+ last_request_body_ = request->FormatRequestBodyForTesting();
+ }
+
+ const std::string& last_request_body() const { return last_request_body_; }
+
+ private:
+ std::string last_request_body_;
+
+ DISALLOW_COPY_AND_ASSIGN(WiFiTestMonitor);
+};
+
class SimpleGeolocationTest : public testing::Test {
private:
base::MessageLoop message_loop_;
};
TEST_F(SimpleGeolocationTest, ResponseOK) {
- SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+ SimpleGeolocationProvider provider(nullptr,
+ GURL(kTestGeolocationProviderUrl));
GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
std::string(kSimpleResponseBody),
@@ -176,21 +220,19 @@ TEST_F(SimpleGeolocationTest, ResponseOK) {
&provider);
GeolocationReceiver receiver;
- provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1), false,
base::Bind(&GeolocationReceiver::OnRequestDone,
base::Unretained(&receiver)));
receiver.WaitUntilRequestDone();
- EXPECT_EQ(
- "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
- "error_code=0, error_message='', status=1 (OK)",
- receiver.position().ToString());
+ EXPECT_EQ(kExpectedPosition, receiver.position().ToString());
EXPECT_FALSE(receiver.server_error());
EXPECT_EQ(1U, url_factory.attempts());
}
TEST_F(SimpleGeolocationTest, ResponseOKWithRetries) {
- SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+ SimpleGeolocationProvider provider(nullptr,
+ GURL(kTestGeolocationProviderUrl));
GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
std::string(kSimpleResponseBody),
@@ -198,20 +240,18 @@ TEST_F(SimpleGeolocationTest, ResponseOKWithRetries) {
&provider);
GeolocationReceiver receiver;
- provider.RequestGeolocation(base::TimeDelta::FromSeconds(1),
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1), false,
base::Bind(&GeolocationReceiver::OnRequestDone,
base::Unretained(&receiver)));
receiver.WaitUntilRequestDone();
- EXPECT_EQ(
- "latitude=51.000000, longitude=-0.100000, accuracy=1200.400000, "
- "error_code=0, error_message='', status=1 (OK)",
- receiver.position().ToString());
+ EXPECT_EQ(kExpectedPosition, receiver.position().ToString());
EXPECT_FALSE(receiver.server_error());
EXPECT_EQ(4U, url_factory.attempts());
}
TEST_F(SimpleGeolocationTest, InvalidResponse) {
- SimpleGeolocationProvider provider(NULL, GURL(kTestGeolocationProviderUrl));
+ SimpleGeolocationProvider provider(nullptr,
+ GURL(kTestGeolocationProviderUrl));
GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
"invalid JSON string",
@@ -226,6 +266,7 @@ TEST_F(SimpleGeolocationTest, InvalidResponse) {
ASSERT_GE(expected_retries, 2U);
provider.RequestGeolocation(base::TimeDelta::FromSeconds(timeout_seconds),
+ false,
base::Bind(&GeolocationReceiver::OnRequestDone,
base::Unretained(&receiver)));
receiver.WaitUntilRequestDone();
@@ -252,4 +293,155 @@ TEST_F(SimpleGeolocationTest, InvalidResponse) {
}
}
+TEST_F(SimpleGeolocationTest, NoWiFi) {
+ // This initializes DBusThreadManager and markes it "for tests only".
+ DBusThreadManager::GetSetterForTesting();
+ NetworkHandler::Initialize();
+
+ WiFiTestMonitor requests_monitor;
+ SimpleGeolocationRequest::SetTestMonitor(&requests_monitor);
+
+ SimpleGeolocationProvider provider(nullptr,
+ GURL(kTestGeolocationProviderUrl));
+
+ GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
+ std::string(kSimpleResponseBody),
+ 0 /* require_retries */, &provider);
+
+ GeolocationReceiver receiver;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1), true,
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+ EXPECT_EQ(kIPOnlyRequestBody, requests_monitor.last_request_body());
+
+ EXPECT_EQ(kExpectedPosition, receiver.position().ToString());
+ EXPECT_FALSE(receiver.server_error());
+ EXPECT_EQ(1U, url_factory.attempts());
+
+ NetworkHandler::Shutdown();
+ DBusThreadManager::Shutdown();
+}
+
+// Test sending of WiFi Access points.
+// (This is mostly derived from GeolocationHandlerTest.)
+class SimpleGeolocationWiFiTest : public ::testing::TestWithParam<bool> {
+ public:
+ SimpleGeolocationWiFiTest() : manager_test_(nullptr) {}
+
+ ~SimpleGeolocationWiFiTest() override {}
+
+ void SetUp() override {
+ // This initializes DBusThreadManager and markes it "for tests only".
+ DBusThreadManager::GetSetterForTesting();
+ // Get the test interface for manager / device.
+ manager_test_ =
+ DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
+ ASSERT_TRUE(manager_test_);
+ geolocation_handler_.reset(new GeolocationHandler());
+ geolocation_handler_->Init();
+ message_loop_.RunUntilIdle();
+ }
+
+ void TearDown() override {
+ geolocation_handler_.reset();
+ DBusThreadManager::Shutdown();
+ }
+
+ bool GetWifiAccessPoints() {
+ return geolocation_handler_->GetWifiAccessPoints(&wifi_access_points_,
+ nullptr);
+ }
+
+ void AddAccessPoint(int idx) {
+ base::DictionaryValue properties;
+ std::string mac_address =
+ base::StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X", idx, 0, 0, 0, 0, 0);
+ std::string channel = base::IntToString(idx);
+ std::string strength = base::IntToString(idx * 10);
+ properties.SetStringWithoutPathExpansion(shill::kGeoMacAddressProperty,
+ mac_address);
+ properties.SetStringWithoutPathExpansion(shill::kGeoChannelProperty,
+ channel);
+ properties.SetStringWithoutPathExpansion(shill::kGeoSignalStrengthProperty,
+ strength);
+ manager_test_->AddGeoNetwork(shill::kTypeWifi, properties);
+ message_loop_.RunUntilIdle();
+ }
+
+ protected:
+ base::MessageLoopForUI message_loop_;
+ scoped_ptr<GeolocationHandler> geolocation_handler_;
+ ShillManagerClient::TestInterface* manager_test_;
+ WifiAccessPointVector wifi_access_points_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleGeolocationWiFiTest);
+};
+
+// Parameter is enable/disable sending of WiFi data.
+TEST_P(SimpleGeolocationWiFiTest, WiFiExists) {
+ NetworkHandler::Initialize();
+
+ WiFiTestMonitor requests_monitor;
+ SimpleGeolocationRequest::SetTestMonitor(&requests_monitor);
+
+ SimpleGeolocationProvider provider(nullptr,
+ GURL(kTestGeolocationProviderUrl));
+
+ GeolocationAPIFetcherFactory url_factory(GURL(kTestGeolocationProviderUrl),
+ std::string(kSimpleResponseBody),
+ 0 /* require_retries */, &provider);
+ {
+ GeolocationReceiver receiver;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1), GetParam(),
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+ EXPECT_EQ(kIPOnlyRequestBody, requests_monitor.last_request_body());
+
+ EXPECT_EQ(kExpectedPosition, receiver.position().ToString());
+ EXPECT_FALSE(receiver.server_error());
+ EXPECT_EQ(1U, url_factory.attempts());
+ }
+
+ // Add an acces point.
+ AddAccessPoint(1);
+ message_loop_.RunUntilIdle();
+ // Inititial call should return false and request access points.
+ EXPECT_FALSE(GetWifiAccessPoints());
+ message_loop_.RunUntilIdle();
+ // Second call should return true since we have an access point.
+ EXPECT_TRUE(GetWifiAccessPoints());
+ ASSERT_EQ(1u, wifi_access_points_.size());
+ EXPECT_EQ(kWiFiAP1MacAddress, wifi_access_points_[0].mac_address);
+ EXPECT_EQ(1, wifi_access_points_[0].channel);
+
+ {
+ GeolocationReceiver receiver;
+ provider.RequestGeolocation(base::TimeDelta::FromSeconds(1), GetParam(),
+ base::Bind(&GeolocationReceiver::OnRequestDone,
+ base::Unretained(&receiver)));
+ receiver.WaitUntilRequestDone();
+ if (GetParam()) {
+ // Sending WiFi data is enabled.
+ EXPECT_EQ(kOneWiFiAPRequestBody, requests_monitor.last_request_body());
+ } else {
+ // Sending WiFi data is disabled.
+ EXPECT_EQ(kIPOnlyRequestBody, requests_monitor.last_request_body());
+ }
+
+ EXPECT_EQ(kExpectedPosition, receiver.position().ToString());
+ EXPECT_FALSE(receiver.server_error());
+ // This is total.
+ EXPECT_EQ(2U, url_factory.attempts());
+ }
+ NetworkHandler::Shutdown();
+}
+
+// This test verifies that WiFi data is sent only if sending was requested.
+INSTANTIATE_TEST_CASE_P(EnableDisableSendingWifiData,
+ SimpleGeolocationWiFiTest,
+ testing::Bool());
+
} // namespace chromeos
diff --git a/chromeos/network/geolocation_handler.h b/chromeos/network/geolocation_handler.h
index 5720364..f962328 100644
--- a/chromeos/network/geolocation_handler.h
+++ b/chromeos/network/geolocation_handler.h
@@ -52,6 +52,8 @@ class CHROMEOS_EXPORT GeolocationHandler : public ShillPropertyChangedObserver {
private:
friend class NetworkHandler;
friend class GeolocationHandlerTest;
+ friend class SimpleGeolocationWiFiTest;
+
GeolocationHandler();
void Init();
diff --git a/chromeos/timezone/timezone_resolver.cc b/chromeos/timezone/timezone_resolver.cc
index c6ebfb4..9e4c7b9 100644
--- a/chromeos/timezone/timezone_resolver.cc
+++ b/chromeos/timezone/timezone_resolver.cc
@@ -183,6 +183,7 @@ void TZRequest::StartRequestOnNetworkAvailable() {
resolver_->RecordAttempt();
resolver_->geolocation_provider()->RequestGeolocation(
base::TimeDelta::FromSeconds(kRefreshTimeZoneTimeoutSeconds),
+ false /* send_wifi_geolocation_data */,
base::Bind(&TZRequest::OnLocationResolved, AsWeakPtr()));
}
@@ -383,7 +384,8 @@ TimeZoneResolver::TimeZoneResolver(
url_(url),
apply_timezone_(apply_timezone),
delay_network_call_(delay_network_call),
- local_state_(local_state) {
+ local_state_(local_state),
+ send_wifi_data_to_geolocation_api_(false) {
DCHECK(!apply_timezone.is_null());
}
diff --git a/chromeos/timezone/timezone_resolver.h b/chromeos/timezone/timezone_resolver.h
index 231575b..35e6c2e 100644
--- a/chromeos/timezone/timezone_resolver.h
+++ b/chromeos/timezone/timezone_resolver.h
@@ -79,6 +79,8 @@ class CHROMEOS_EXPORT TimeZoneResolver {
scoped_ptr<TimeZoneResolverImpl> implementation_;
+ bool send_wifi_data_to_geolocation_api_;
+
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(TimeZoneResolver);