summaryrefslogtreecommitdiff
path: root/chromium/components/language
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-01-31 16:33:43 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-06 16:33:22 +0000
commitda51f56cc21233c2d30f0fe0d171727c3102b2e0 (patch)
tree4e579ab70ce4b19bee7984237f3ce05a96d59d83 /chromium/components/language
parentc8c2d1901aec01e934adf561a9fdf0cc776cdef8 (diff)
downloadqtwebengine-chromium-da51f56cc21233c2d30f0fe0d171727c3102b2e0.tar.gz
BASELINE: Update Chromium to 65.0.3525.40
Also imports missing submodules Change-Id: I36901b7c6a325cda3d2c10cedb2186c25af3b79b Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/language')
-rw-r--r--chromium/components/language/README4
-rw-r--r--chromium/components/language/content/browser/BUILD.gn (renamed from chromium/components/language/BUILD.gn)24
-rw-r--r--chromium/components/language/content/browser/DEPS5
-rw-r--r--chromium/components/language/content/browser/README3
-rw-r--r--chromium/components/language/content/browser/adminregionsdata.csv (renamed from chromium/components/language/adminregionsdata.csv)0
-rw-r--r--chromium/components/language/content/browser/convert_s2_cell.py132
-rw-r--r--chromium/components/language/content/browser/geo_language_provider.cc153
-rw-r--r--chromium/components/language/content/browser/geo_language_provider.h114
-rw-r--r--chromium/components/language/content/browser/geo_language_provider_unittest.cc183
-rw-r--r--chromium/components/language/content/browser/language_code_locator.cc48
-rw-r--r--chromium/components/language/content/browser/language_code_locator.h (renamed from chromium/components/language/language_code_locator.h)10
-rw-r--r--chromium/components/language/content/browser/language_code_locator_unittest.cc (renamed from chromium/components/language/language_code_locator_unittest.cc)12
-rw-r--r--chromium/components/language/content/browser/template/language_code_locator_helper.h.tmpl33
-rw-r--r--chromium/components/language/convert_s2_cell.py83
-rw-r--r--chromium/components/language/language_code_locator.cc37
-rw-r--r--chromium/components/language/template/language_code_locator_helper.cc.tmpl22
16 files changed, 707 insertions, 156 deletions
diff --git a/chromium/components/language/README b/chromium/components/language/README
index 15ce9d425c3..e4c4821cc4c 100644
--- a/chromium/components/language/README
+++ b/chromium/components/language/README
@@ -13,7 +13,3 @@ content/: Driver for the shared code based on the content layer.
renderer/: Renderer process code.
common/: Code shared by the browser and the renderer.
ios/: Driver for the shared code based on src/ios.
-
-Note:
-The language code locator is built on all platforms but iOS since iOS currently
-does not support //device/geolocation. See http://crbug.com/774879 for details.
diff --git a/chromium/components/language/BUILD.gn b/chromium/components/language/content/browser/BUILD.gn
index b77574817d2..06b29c29d6f 100644
--- a/chromium/components/language/BUILD.gn
+++ b/chromium/components/language/content/browser/BUILD.gn
@@ -10,10 +10,10 @@ action("make_s2_language_locator") {
"adminregionsdata.csv",
]
inputs = [
- "template/language_code_locator_helper.cc.tmpl",
+ "template/language_code_locator_helper.h.tmpl",
]
outputs = [
- "$target_gen_dir/language_code_locator_helper.cc",
+ "$target_gen_dir/language_code_locator_helper.h",
]
args = [
@@ -35,14 +35,34 @@ source_set("language_code_locator") {
]
}
+static_library("browser") {
+ sources = [
+ "geo_language_provider.cc",
+ "geo_language_provider.h",
+ ]
+
+ deps = [
+ ":language_code_locator",
+ "//base",
+ "//net",
+ "//services/device/public/interfaces:interfaces",
+ "//services/service_manager/public/cpp",
+ ]
+}
+
source_set("unit_tests") {
testonly = true
sources = [
+ "geo_language_provider_unittest.cc",
"language_code_locator_unittest.cc",
]
deps = [
+ ":browser",
":language_code_locator",
"//base",
+ "//base/test:test_support",
+ "//services/device/public/interfaces:interfaces",
+ "//services/service_manager/public/cpp",
"//testing/gmock",
"//testing/gtest",
]
diff --git a/chromium/components/language/content/browser/DEPS b/chromium/components/language/content/browser/DEPS
index 1c35d9ca694..9d2ba3a3188 100644
--- a/chromium/components/language/content/browser/DEPS
+++ b/chromium/components/language/content/browser/DEPS
@@ -1,3 +1,6 @@
include_rules = [
- "+content/public/browser",
+ "+device/geolocation/public/interfaces",
+ "+net",
+ "+services/device/public/interfaces",
+ "+services/service_manager/public",
]
diff --git a/chromium/components/language/content/browser/README b/chromium/components/language/content/browser/README
new file mode 100644
index 00000000000..3ce50f2b614
--- /dev/null
+++ b/chromium/components/language/content/browser/README
@@ -0,0 +1,3 @@
+Note:
+The language code locator is built on all platforms but iOS since iOS currently
+does not support //device/geolocation. See http://crbug.com/774879 for details.
diff --git a/chromium/components/language/adminregionsdata.csv b/chromium/components/language/content/browser/adminregionsdata.csv
index bbc58dcc2b4..bbc58dcc2b4 100644
--- a/chromium/components/language/adminregionsdata.csv
+++ b/chromium/components/language/content/browser/adminregionsdata.csv
diff --git a/chromium/components/language/content/browser/convert_s2_cell.py b/chromium/components/language/content/browser/convert_s2_cell.py
new file mode 100644
index 00000000000..1c6be45ff16
--- /dev/null
+++ b/chromium/components/language/content/browser/convert_s2_cell.py
@@ -0,0 +1,132 @@
+# Copyright 2017 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.
+
+"""Generate c++ structure mapping position to language code from .csv input."""
+
+import argparse
+import csv
+import os.path
+import string
+import sys
+
+sys.path.insert(1,
+ os.path.join(os.path.dirname(__file__),
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ os.path.pardir,
+ "third_party"))
+import jinja2 # pylint: disable=F0401
+
+
+CELL_ID_FIELD = "cell_ids"
+LANGUAGE_FIELD = "languages"
+
+
+def ParseInputCsv(input_path):
+ """Derive cell_id : language_code pairs."""
+ district_with_languages = []
+ with open(input_path, "r") as f:
+ reader = csv.DictReader(f, delimiter=",")
+ for row in reader:
+ district_with_languages.append((row[LANGUAGE_FIELD],
+ row[CELL_ID_FIELD]))
+ return district_with_languages
+
+
+def ExtractCellIds(language_districts):
+ """Convert <language code>: [<cell_ids>...] into
+ a list of cell_id : language_code pairs."""
+ cell_language_code_pairs = []
+ language_code_enum = {}
+ for language_code, cell_ids in language_districts:
+ cell_ids = cell_ids.split(";")
+ for cell_id in cell_ids:
+ # We only store a coarser cell_ids (represent using uint32_t)
+ # to reduce binary size.
+ coarse_cell_id = cell_id[:-8]
+ # Change language code to language_enum to save some space.
+ if not language_code_enum.has_key(language_code):
+ language_code_enum[language_code] = len(language_code_enum)
+ language_enum = language_code_enum[language_code]
+ cell_language_code_pairs.append((coarse_cell_id, language_enum))
+ return cell_language_code_pairs, language_code_enum
+
+
+def ExtractLanguageCodeCounts(cell_language_code_pairs):
+ """Convert a list of cell_id : language_code pairs to cell_ids and counts"""
+ language_code_cell_id = {}
+ for cell_lang in cell_language_code_pairs:
+ if not language_code_cell_id.has_key(cell_lang[1]):
+ language_code_cell_id[cell_lang[1]] = []
+ language_code_cell_id[cell_lang[1]].append(cell_lang[0])
+ language_counts = []
+ cell_ids = []
+ for i in range(len(language_code_cell_id)):
+ language_counts.append(len(language_code_cell_id[i]))
+ cell_ids.extend(language_code_cell_id[i])
+ return cell_ids, language_counts
+
+
+def ExtractLanguageCodeEnum(language_code_enum):
+ """Convert language code enum dictionary to array."""
+ language_codes = []
+ inverted_lanugage_code_enum = dict(
+ [[v, k] for k, v in language_code_enum.items()])
+ for i in range(len(inverted_lanugage_code_enum)):
+ language_codes.append(inverted_lanugage_code_enum[i])
+ return language_codes
+
+
+def GenerateCpp(output_path,
+ template_path,
+ cell_ids,
+ language_counts,
+ language_codes):
+ """Render the template to generate cpp code for LanguageCodeLocator."""
+ with open(template_path, "r") as f:
+ template = jinja2.Template(f.read())
+ context = {
+ "cell_ids" : cell_ids,
+ "language_counts" : language_counts,
+ "language_codes" : language_codes
+ }
+ generated_code = template.render(context)
+
+ # Write the generated code.
+ with open(output_path, "w") as f:
+ f.write(generated_code)
+
+
+def Main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--outputs", "-o", required=True,
+ help="path to the generate c++ file")
+ parser.add_argument(
+ "--template", "-t", required=True,
+ help="path to the template used to generate c++ file")
+ parser.add_argument(
+ "--inputs", "-i", required=True,
+ help="path to the input .csv file")
+ args = parser.parse_args()
+
+ output_path = args.outputs
+ template_file_path = args.template
+ data_file_path = args.inputs
+
+ cell_language_code_pairs, language_code_enum = ExtractCellIds(
+ ParseInputCsv(data_file_path))
+
+ cell_ids, language_counts = ExtractLanguageCodeCounts(
+ cell_language_code_pairs)
+ language_codes = ExtractLanguageCodeEnum(language_code_enum)
+ GenerateCpp(output_path,
+ template_file_path,
+ cell_ids,
+ language_counts,
+ language_codes)
+
+if __name__ == "__main__":
+ Main()
diff --git a/chromium/components/language/content/browser/geo_language_provider.cc b/chromium/components/language/content/browser/geo_language_provider.cc
new file mode 100644
index 00000000000..b06bb4743c9
--- /dev/null
+++ b/chromium/components/language/content/browser/geo_language_provider.cc
@@ -0,0 +1,153 @@
+// Copyright 2017 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 "components/language/content/browser/geo_language_provider.h"
+
+#include "base/memory/singleton.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/time/time.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/device/public/interfaces/constants.mojom.h"
+#include "services/device/public/interfaces/public_ip_address_geolocation_provider.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace language {
+namespace {
+
+// Don't start requesting updates to IP-based approximation geolocation until
+// this long after receiving the last one.
+constexpr base::TimeDelta kMinUpdatePeriod = base::TimeDelta::FromDays(1);
+
+} // namespace
+
+GeoLanguageProvider::GeoLanguageProvider()
+ : languages_(),
+ creation_task_runner_(base::SequencedTaskRunnerHandle::Get()),
+ background_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
+ // Constructor is not required to run on |background_task_runner_|:
+ DETACH_FROM_SEQUENCE(background_sequence_checker_);
+}
+
+GeoLanguageProvider::GeoLanguageProvider(
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner)
+ : languages_(),
+ creation_task_runner_(base::SequencedTaskRunnerHandle::Get()),
+ background_task_runner_(background_task_runner) {
+ // Constructor is not required to run on |background_task_runner_|:
+ DETACH_FROM_SEQUENCE(background_sequence_checker_);
+}
+
+GeoLanguageProvider::~GeoLanguageProvider() = default;
+
+/* static */
+GeoLanguageProvider* GeoLanguageProvider::GetInstance() {
+ return base::Singleton<GeoLanguageProvider, base::LeakySingletonTraits<
+ GeoLanguageProvider>>::get();
+}
+
+void GeoLanguageProvider::StartUp(
+ std::unique_ptr<service_manager::Connector> service_manager_connector) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(creation_sequence_checker_);
+
+ service_manager_connector_ = std::move(service_manager_connector);
+ // Continue startup in the background.
+ background_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&GeoLanguageProvider::BackgroundStartUp,
+ base::Unretained(this)));
+}
+
+std::vector<std::string> GeoLanguageProvider::CurrentGeoLanguages() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(creation_sequence_checker_);
+ return languages_;
+}
+
+void GeoLanguageProvider::BackgroundStartUp() {
+ // This binds background_sequence_checker_.
+ DCHECK_CALLED_ON_VALID_SEQUENCE(background_sequence_checker_);
+
+ // Initialize location->language lookup library.
+ language_code_locator_ = std::make_unique<language::LanguageCodeLocator>();
+
+ // Make initial query.
+ QueryNextPosition();
+}
+
+void GeoLanguageProvider::BindIpGeolocationService() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(background_sequence_checker_);
+ DCHECK(!geolocation_provider_.is_bound());
+
+ // Bind a PublicIpAddressGeolocationProvider.
+ device::mojom::PublicIpAddressGeolocationProviderPtr ip_geolocation_provider;
+ service_manager_connector_->BindInterface(
+ device::mojom::kServiceName, mojo::MakeRequest(&ip_geolocation_provider));
+
+ net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
+ net::DefinePartialNetworkTrafficAnnotation("geo_language_provider",
+ "network_location_request",
+ R"(
+ semantics {
+ sender: "GeoLanguage Provider"
+ }
+ policy {
+ setting:
+ "Users can control this feature via the translation settings "
+ "'Languages', 'Language', 'Offer to translate'."
+ chrome_policy {
+ DefaultGeolocationSetting {
+ DefaultGeolocationSetting: 2
+ }
+ }
+ })");
+
+ // Use the PublicIpAddressGeolocationProvider to bind ip_geolocation_service_.
+ ip_geolocation_provider->CreateGeolocation(
+ static_cast<net::MutablePartialNetworkTrafficAnnotationTag>(
+ partial_traffic_annotation),
+ mojo::MakeRequest(&geolocation_provider_));
+ // No error handler required: If the connection is broken, QueryNextPosition
+ // will bind it again.
+}
+
+void GeoLanguageProvider::QueryNextPosition() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(background_sequence_checker_);
+
+ if (geolocation_provider_.encountered_error())
+ geolocation_provider_.reset();
+ if (!geolocation_provider_.is_bound())
+ BindIpGeolocationService();
+
+ geolocation_provider_->QueryNextPosition(base::BindOnce(
+ &GeoLanguageProvider::OnIpGeolocationResponse, base::Unretained(this)));
+}
+
+void GeoLanguageProvider::OnIpGeolocationResponse(
+ device::mojom::GeopositionPtr geoposition) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(background_sequence_checker_);
+
+ const std::vector<std::string> languages =
+ language_code_locator_->GetLanguageCode(geoposition->latitude,
+ geoposition->longitude);
+
+ // Update current languages on UI thread.
+ creation_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&GeoLanguageProvider::SetGeoLanguages,
+ base::Unretained(this), languages));
+
+ // Post a task to request a fresh lookup after |kMinUpdatePeriod|.
+ background_task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&GeoLanguageProvider::QueryNextPosition,
+ base::Unretained(this)),
+ kMinUpdatePeriod);
+}
+
+void GeoLanguageProvider::SetGeoLanguages(
+ const std::vector<std::string>& languages) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(creation_sequence_checker_);
+ languages_ = languages;
+}
+
+} // namespace language
diff --git a/chromium/components/language/content/browser/geo_language_provider.h b/chromium/components/language/content/browser/geo_language_provider.h
new file mode 100644
index 00000000000..b361a639926
--- /dev/null
+++ b/chromium/components/language/content/browser/geo_language_provider.h
@@ -0,0 +1,114 @@
+// Copyright 2017 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 COMPONENTS_LANGUAGE_CONTENT_BROWSER_GEO_LANGUAGE_PROVIDER_H_
+#define COMPONENTS_LANGUAGE_CONTENT_BROWSER_GEO_LANGUAGE_PROVIDER_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
+#include "base/sequenced_task_runner.h"
+#include "components/language/content/browser/language_code_locator.h"
+#include "device/geolocation/public/interfaces/geolocation.mojom.h"
+
+namespace base {
+template <typename T>
+struct DefaultSingletonTraits;
+}
+
+namespace service_manager {
+class Connector;
+}
+
+namespace language {
+// GeoLanguageProvider is responsible for providing a "local" language derived
+// from the approximate geolocation of the device based only on its public IP
+// address.
+// * Singleton class. Access through GetInstance().
+// * Sequencing: Must be created and used on the same sequence.
+class GeoLanguageProvider {
+ public:
+ static GeoLanguageProvider* GetInstance();
+
+ // Call this once near browser startup. Begins ongoing geo-language updates.
+ // * Initializes location->language mapping in a low-priority background task.
+ // * Until the first IP geolocation completes, CurrentGeoLanguages() will
+ // return an empty list.
+ // |service_manager_connector| should not yet be bound to a sequence, e.g., it
+ // should be the result of invoking ServiceManagerConnect::Clone() on another
+ // connector.
+ void StartUp(
+ std::unique_ptr<service_manager::Connector> service_manager_connector);
+
+ // Returns the inferred ranked list of local languages based on the most
+ // recently obtained approximate public-IP geolocation of the device.
+ // * Returns a list of BCP-47 language codes.
+ // * Returns an empty list in these cases:
+ // - StartUp() not yet called
+ // - Geolocation failed
+ // - Geolocation pending
+ // - Geolocation succeeded but no local language is mapped to that location
+ std::vector<std::string> CurrentGeoLanguages() const;
+
+ private:
+ friend class GeoLanguageProviderTest;
+
+ GeoLanguageProvider();
+ explicit GeoLanguageProvider(
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner);
+ ~GeoLanguageProvider();
+ friend struct base::DefaultSingletonTraits<GeoLanguageProvider>;
+
+ // Performs actual work described in StartUp() above.
+ void BackgroundStartUp();
+
+ // Binds |ip_geolocation_service_| using a service_manager::Connector.
+ void BindIpGeolocationService();
+
+ // Requests the next available IP-based approximate geolocation from
+ // |ip_geolocation_service_|, binding |ip_geolocation_service_| first if
+ // necessary.
+ void QueryNextPosition();
+
+ // Updates the list of BCP-47 language codes that will be returned by calls to
+ // CurrentGeoLanguages().
+ // Must be called on the UI thread.
+ void SetGeoLanguages(const std::vector<std::string>& languages);
+
+ // Callback for updates from |ip_geolocation_service_|.
+ void OnIpGeolocationResponse(device::mojom::GeopositionPtr geoposition);
+
+ // List of BCP-47 language code inferred from public-IP geolocation.
+ // May be empty. See comment on CurrentGeoLanguages() above.
+ std::vector<std::string> languages_;
+
+ // Service manager connector for use on background_task_runner_.
+ std::unique_ptr<service_manager::Connector> service_manager_connector_;
+
+ // Connection to the IP geolocation service.
+ device::mojom::GeolocationPtr geolocation_provider_;
+
+ // Location -> Language lookup library.
+ std::unique_ptr<language::LanguageCodeLocator> language_code_locator_;
+
+ // Runner for tasks that should run on the creation sequence.
+ scoped_refptr<base::SequencedTaskRunner> creation_task_runner_;
+
+ // Runner for low priority background tasks.
+ scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
+
+ // Sequence checker for methods that must run on the creation sequence.
+ SEQUENCE_CHECKER(creation_sequence_checker_);
+
+ // Sequence checker for background_task_runner_.
+ SEQUENCE_CHECKER(background_sequence_checker_);
+
+ DISALLOW_COPY_AND_ASSIGN(GeoLanguageProvider);
+};
+
+} // namespace language
+
+#endif // COMPONENTS_LANGUAGE_CONTENT_BROWSER_GEO_LANGUAGE_PROVIDER_H_
diff --git a/chromium/components/language/content/browser/geo_language_provider_unittest.cc b/chromium/components/language/content/browser/geo_language_provider_unittest.cc
new file mode 100644
index 00000000000..bb73e412492
--- /dev/null
+++ b/chromium/components/language/content/browser/geo_language_provider_unittest.cc
@@ -0,0 +1,183 @@
+// Copyright 2017 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 "components/language/content/browser/geo_language_provider.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/timer/timer.h"
+#include "device/geolocation/public/interfaces/geolocation.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/device/public/interfaces/constants.mojom.h"
+#include "services/device/public/interfaces/public_ip_address_geolocation_provider.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/public/interfaces/connector.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// Mock impl of mojom::Geolocation that allows tests to control the returned
+// location.
+class MockGeoLocation : public device::mojom::Geolocation {
+ public:
+ MockGeoLocation() : binding_(this) {}
+ // device::mojom::Geolocation implementation:
+ void SetHighAccuracy(bool high_accuracy) override {}
+ void QueryNextPosition(QueryNextPositionCallback callback) override {
+ ++query_next_position_called_times_;
+ std::move(callback).Run(position_.Clone());
+ }
+
+ void BindGeoLocation(device::mojom::GeolocationRequest request) {
+ binding_.Bind(std::move(request));
+ }
+
+ void MoveToLocation(float latitude, float longitude) {
+ position_.latitude = latitude;
+ position_.longitude = longitude;
+ }
+
+ int query_next_position_called_times() const {
+ return query_next_position_called_times_;
+ }
+
+ private:
+ int query_next_position_called_times_ = 0;
+ device::mojom::Geoposition position_;
+ mojo::Binding<device::mojom::Geolocation> binding_;
+};
+
+// Mock impl of mojom::PublicIpAddressGeolocationProvider that binds Geolocation
+// to testing impl.
+class MockIpGeoLocationProvider
+ : public device::mojom::PublicIpAddressGeolocationProvider {
+ public:
+ explicit MockIpGeoLocationProvider(MockGeoLocation* mock_geo_location)
+ : mock_geo_location_(mock_geo_location), binding_(this) {}
+
+ void Bind(mojo::ScopedMessagePipeHandle handle) {
+ binding_.Bind(device::mojom::PublicIpAddressGeolocationProviderRequest(
+ std::move(handle)));
+ }
+
+ void CreateGeolocation(
+ const net::MutablePartialNetworkTrafficAnnotationTag& /* unused */,
+ device::mojom::GeolocationRequest request) override {
+ mock_geo_location_->BindGeoLocation(std::move(request));
+ }
+
+ private:
+ MockGeoLocation* mock_geo_location_;
+
+ mojo::Binding<device::mojom::PublicIpAddressGeolocationProvider> binding_;
+};
+
+} // namespace
+
+namespace language {
+
+class GeoLanguageProviderTest : public testing::Test {
+ public:
+ GeoLanguageProviderTest()
+ : task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::TestMockTimeTaskRunner::Type::kBoundToThread)),
+ scoped_context_(task_runner_.get()),
+ geo_language_provider_(task_runner_),
+ mock_ip_geo_location_provider_(&mock_geo_location_) {
+ service_manager::mojom::ConnectorRequest request;
+ connector_ = service_manager::Connector::Create(&request);
+ service_manager::Connector::TestApi test_api(connector_.get());
+ test_api.OverrideBinderForTesting(
+ device::mojom::kServiceName,
+ device::mojom::PublicIpAddressGeolocationProvider::Name_,
+ base::BindRepeating(&MockIpGeoLocationProvider::Bind,
+ base::Unretained(&mock_ip_geo_location_provider_)));
+ }
+
+ protected:
+ std::vector<std::string> GetCurrentGeoLanguages() {
+ return geo_language_provider_.CurrentGeoLanguages();
+ }
+
+ void StartGeoLanguageProvider() {
+ geo_language_provider_.StartUp(std::move(connector_));
+ }
+
+ void MoveToLocation(float latitude, float longitude) {
+ mock_geo_location_.MoveToLocation(latitude, longitude);
+ }
+
+ const scoped_refptr<base::TestMockTimeTaskRunner>& GetTaskRunner() {
+ return task_runner_;
+ }
+
+ int GetQueryNextPositionCalledTimes() {
+ return mock_geo_location_.query_next_position_called_times();
+ }
+
+ private:
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
+ const base::TestMockTimeTaskRunner::ScopedContext scoped_context_;
+
+ // Object under test.
+ GeoLanguageProvider geo_language_provider_;
+ MockGeoLocation mock_geo_location_;
+ MockIpGeoLocationProvider mock_ip_geo_location_provider_;
+ std::unique_ptr<service_manager::Connector> connector_;
+};
+
+TEST_F(GeoLanguageProviderTest, GetCurrentGeoLanguages) {
+ // Setup a random place in Madhya Pradesh, India.
+ MoveToLocation(23.0, 80.0);
+ StartGeoLanguageProvider();
+ const auto task_runner = GetTaskRunner();
+ task_runner->RunUntilIdle();
+
+ const std::vector<std::string>& result = GetCurrentGeoLanguages();
+ std::vector<std::string> expected_langs = {"hi", "mr", "ur"};
+ EXPECT_EQ(expected_langs, result);
+ EXPECT_EQ(1, GetQueryNextPositionCalledTimes());
+}
+
+TEST_F(GeoLanguageProviderTest, NoFrequentCalls) {
+ // Setup a random place in Madhya Pradesh, India.
+ MoveToLocation(23.0, 80.0);
+ StartGeoLanguageProvider();
+ const auto task_runner = GetTaskRunner();
+ task_runner->RunUntilIdle();
+
+ const std::vector<std::string>& result = GetCurrentGeoLanguages();
+ std::vector<std::string> expected_langs = {"hi", "mr", "ur"};
+ EXPECT_EQ(expected_langs, result);
+
+ task_runner->FastForwardBy(base::TimeDelta::FromHours(12));
+ EXPECT_EQ(1, GetQueryNextPositionCalledTimes());
+}
+
+TEST_F(GeoLanguageProviderTest, ButDoCallInTheNextDay) {
+ // Setup a random place in Madhya Pradesh, India.
+ MoveToLocation(23.0, 80.0);
+ StartGeoLanguageProvider();
+ const auto task_runner = GetTaskRunner();
+ task_runner->RunUntilIdle();
+
+ std::vector<std::string> result = GetCurrentGeoLanguages();
+ std::vector<std::string> expected_langs = {"hi", "mr", "ur"};
+ EXPECT_EQ(expected_langs, result);
+
+ // Move to another random place in Karnataka, India.
+ MoveToLocation(15.0, 75.0);
+ task_runner->FastForwardBy(base::TimeDelta::FromHours(25));
+ EXPECT_EQ(2, GetQueryNextPositionCalledTimes());
+
+ result = GetCurrentGeoLanguages();
+ std::vector<std::string> expected_langs_2 = {"kn", "ur", "te", "mr", "ta"};
+ EXPECT_EQ(expected_langs_2, result);
+}
+
+} // namespace language
diff --git a/chromium/components/language/content/browser/language_code_locator.cc b/chromium/components/language/content/browser/language_code_locator.cc
new file mode 100644
index 00000000000..0530d7264c3
--- /dev/null
+++ b/chromium/components/language/content/browser/language_code_locator.cc
@@ -0,0 +1,48 @@
+// Copyright 2017 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 "components/language/content/browser/language_code_locator.h"
+
+#include "base/strings/string_split.h"
+#include "third_party/s2cellid/src/s2/s2cellid.h"
+#include "third_party/s2cellid/src/s2/s2latlng.h"
+
+namespace language {
+namespace {
+#include "components/language/content/browser/language_code_locator_helper.h"
+} // namespace
+
+LanguageCodeLocator::LanguageCodeLocator() {
+ int pos = 0;
+ int index = 0;
+ std::vector<std::pair<uint32_t, char>> items(arraysize(kDistrictPositions));
+ for (const uint16_t language_count : kLanguageCodeCounts) {
+ for (int i = 0; i < language_count; ++i) {
+ items[pos] = std::make_pair(kDistrictPositions[pos], index);
+ ++pos;
+ }
+ ++index;
+ }
+ district_languages_ = base::flat_map<uint32_t, char>(items);
+}
+
+LanguageCodeLocator::~LanguageCodeLocator() {}
+
+std::vector<std::string> LanguageCodeLocator::GetLanguageCode(
+ double latitude,
+ double longitude) const {
+ S2CellId current_cell(S2LatLng::FromDegrees(latitude, longitude));
+ while (current_cell.level() > 0) {
+ auto search = district_languages_.find(current_cell.id() >> 32);
+ if (search != district_languages_.end()) {
+ return base::SplitString(
+ kLanguageEnumCodeMapping[static_cast<uint8_t>(search->second)], ";",
+ base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ }
+ current_cell = current_cell.parent();
+ }
+ return {};
+}
+
+} // namespace language
diff --git a/chromium/components/language/language_code_locator.h b/chromium/components/language/content/browser/language_code_locator.h
index 3cc9ac66867..ef07e739a09 100644
--- a/chromium/components/language/language_code_locator.h
+++ b/chromium/components/language/content/browser/language_code_locator.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_LANGUAGE_LANGUAGE_CODE_LOCATOR_H_
-#define COMPONENTS_LANGUAGE_LANGUAGE_CODE_LOCATOR_H_
+#ifndef COMPONENTS_LANGUAGE_CONTENT_BROWSER_LANGUAGE_CODE_LOCATOR_H_
+#define COMPONENTS_LANGUAGE_CONTENT_BROWSER_LANGUAGE_CODE_LOCATOR_H_
#include <string>
#include <vector>
@@ -24,12 +24,12 @@ class LanguageCodeLocator {
double longitude) const;
private:
- // Map from s2 cellid to ';' delimited list of language codes.
- const base::flat_map<uint64_t, std::string> district_languages_;
+ // Map from s2 cellid to ';' delimited list of language codes enum.
+ base::flat_map<uint32_t, char> district_languages_;
DISALLOW_COPY_AND_ASSIGN(LanguageCodeLocator);
};
} // namespace language
-#endif // COMPONENTS_LANGUAGE_LANGUAGE_CODE_LOCATOR_H_
+#endif // COMPONENTS_LANGUAGE_CONTENT_BROWSER_LANGUAGE_CODE_LOCATOR_H_
diff --git a/chromium/components/language/language_code_locator_unittest.cc b/chromium/components/language/content/browser/language_code_locator_unittest.cc
index 2553353c5ec..62d5c979014 100644
--- a/chromium/components/language/language_code_locator_unittest.cc
+++ b/chromium/components/language/content/browser/language_code_locator_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/language/language_code_locator.h"
+#include "components/language/content/browser/language_code_locator.h"
#include <string>
#include <vector>
@@ -12,7 +12,7 @@
namespace language {
-TEST(LanguageCodeLocatorTest, LocatedLanguage) {
+TEST(LanguageCodeLocatorTest, LocatedLanguageOne) {
LanguageCodeLocator locator;
std::vector<std::string> expected_langs = {"hi", "mr", "ur"};
// Random place in Madhya Pradesh, expected langs should be hi;mr;ur.
@@ -20,6 +20,14 @@ TEST(LanguageCodeLocatorTest, LocatedLanguage) {
EXPECT_EQ(expected_langs, result);
}
+TEST(LanguageCodeLocatorTest, LocatedLanguageTwo) {
+ LanguageCodeLocator locator;
+ std::vector<std::string> expected_langs = {"bn"};
+ // Random place in Tripura, expected langs should be bn.
+ const auto& result = locator.GetLanguageCode(23.7f, 91.7f);
+ EXPECT_EQ(expected_langs, result);
+}
+
TEST(LanguageCodeLocatorTest, NotFoundLanguage) {
LanguageCodeLocator locator;
std::vector<std::string> expected_langs = {};
diff --git a/chromium/components/language/content/browser/template/language_code_locator_helper.h.tmpl b/chromium/components/language/content/browser/template/language_code_locator_helper.h.tmpl
new file mode 100644
index 00000000000..bcf5ee3a47a
--- /dev/null
+++ b/chromium/components/language/content/browser/template/language_code_locator_helper.h.tmpl
@@ -0,0 +1,33 @@
+// Copyright 2017 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 <string>
+#include <vector>
+
+namespace {
+const uint32_t kDistrictPositions[] = {
+ {% set c = 1 %}
+ {% for cell_id in cell_ids -%}
+ {{cell_id}}u{% if c < cell_ids|length%},{% endif %}
+ {% set c = c + 1%}
+ {%- endfor %}
+};
+
+const uint16_t kLanguageCodeCounts[] = {
+ {% set c = 1 %}
+ {% for language_count in language_counts -%}
+ {{language_count}}u{% if c < language_counts|length%},{% endif %}
+ {% set c = c + 1%}
+ {%- endfor %}
+};
+
+const char* const kLanguageEnumCodeMapping[] = {
+ {% set c = 1 %}
+ {% for language_code in language_codes -%}
+ "{{language_code}}"{% if c < language_codes|length%},{% endif %}
+ {% set c = c + 1%}
+ {%- endfor %}
+};
+
+} // namespace
diff --git a/chromium/components/language/convert_s2_cell.py b/chromium/components/language/convert_s2_cell.py
deleted file mode 100644
index b9646677260..00000000000
--- a/chromium/components/language/convert_s2_cell.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2017 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.
-
-"""Generate c++ structure mapping position to language code from .csv input."""
-
-import argparse
-import csv
-import os.path
-import string
-import sys
-
-sys.path.insert(1,
- os.path.join(os.path.dirname(__file__),
- os.path.pardir,
- os.path.pardir,
- "third_party"))
-import jinja2 # pylint: disable=F0401
-
-
-CELL_ID_FIELD = "cell_ids"
-LANGUAGE_FIELD = "languages"
-
-
-def ParseInputCsv(input_path):
- """Derive cell_id : language_code pairs."""
- district_with_languages = []
- with open(input_path, "r") as f:
- reader = csv.DictReader(f, delimiter=",")
- for row in reader:
- district_with_languages.append((row[LANGUAGE_FIELD],
- row[CELL_ID_FIELD]))
- return district_with_languages
-
-
-def ExtractCellIds(language_districts):
- """Convert <language code>: [<cell_ids>...] into
- a list of cell_id : language_code pairs."""
- cell_language_code_pairs = []
- for language_code, cell_ids in language_districts:
- cell_ids = cell_ids.split(";")
- for cell_id in cell_ids:
- cell_language_code_pairs.append((cell_id, language_code))
- return cell_language_code_pairs
-
-
-def GenerateCpp(output_path, template_path, cell_language_code_pairs):
- """Render the template to generate cpp code for LanguageCodeLocator."""
- with open(template_path, "r") as f:
- template = jinja2.Template(f.read())
- context = {
- "cell_lang_pairs" : cell_language_code_pairs
- }
- generated_code = template.render(context)
-
- # Write the generated code.
- with open(output_path, "w") as f:
- f.write(generated_code)
-
-
-def Main():
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "--outputs", "-o", required=True,
- help="path to the generate c++ file")
- parser.add_argument(
- "--template", "-t", required=True,
- help="path to the template used to generate c++ file")
- parser.add_argument(
- "--inputs", "-i", required=True,
- help="path to the input .csv file")
- args = parser.parse_args()
-
- output_path = args.outputs
- template_file_path = args.template
- data_file_path = args.inputs
-
- cell_language_code_pairs = ExtractCellIds(ParseInputCsv(data_file_path))
-
- GenerateCpp(output_path, template_file_path, cell_language_code_pairs)
-
-if __name__ == "__main__":
- Main()
diff --git a/chromium/components/language/language_code_locator.cc b/chromium/components/language/language_code_locator.cc
deleted file mode 100644
index bb06734cc18..00000000000
--- a/chromium/components/language/language_code_locator.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2017 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 "components/language/language_code_locator.h"
-
-#include "base/strings/string_split.h"
-#include "third_party/s2cellid/src/s2/s2cellid.h"
-#include "third_party/s2cellid/src/s2/s2latlng.h"
-
-namespace language {
-namespace internal {
-extern std::vector<std::pair<uint64_t, std::string>>
-GenerateDistrictLanguageMapping();
-} // namespace internal
-
-LanguageCodeLocator::LanguageCodeLocator()
- : district_languages_(internal::GenerateDistrictLanguageMapping()) {}
-
-LanguageCodeLocator::~LanguageCodeLocator() {}
-
-std::vector<std::string> LanguageCodeLocator::GetLanguageCode(
- double latitude,
- double longitude) const {
- S2CellId current_cell(S2LatLng::FromDegrees(latitude, longitude));
- while (current_cell.level() > 0) {
- auto search = district_languages_.find(current_cell.id());
- if (search != district_languages_.end()) {
- return base::SplitString(search->second, ";", base::KEEP_WHITESPACE,
- base::SPLIT_WANT_ALL);
- }
- current_cell = current_cell.parent();
- }
- return {};
-}
-
-} // namespace language
diff --git a/chromium/components/language/template/language_code_locator_helper.cc.tmpl b/chromium/components/language/template/language_code_locator_helper.cc.tmpl
deleted file mode 100644
index 9c36aa89ee6..00000000000
--- a/chromium/components/language/template/language_code_locator_helper.cc.tmpl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 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 <string>
-#include <vector>
-
-namespace language {
-namespace internal {
-std::vector<std::pair<uint64_t, std::string>>
-GenerateDistrictLanguageMapping() {
- return {
- {% set c = 1 %}
- {% for cell_lang_pair in cell_lang_pairs -%}
- { {{cell_lang_pair[0]}}ull, "{{cell_lang_pair[1]}}"}{% if c < cell_lang_pairs|length%},{% endif %}
- {% set c = c + 1%}
- {%- endfor %}
- };
-}
-
-} // namespace internal
-} // namespace language