123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Copyright 2018 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 "services/device/geolocation/position_cache_impl.h"
- #include <algorithm>
- #include "base/strings/utf_string_conversions.h"
- #include "services/device/geolocation/wifi_data.h"
- #include "services/device/public/mojom/geoposition.mojom.h"
- namespace device {
- // static
- const size_t PositionCacheImpl::kMaximumSize = 10;
- // static
- const base::TimeDelta PositionCacheImpl::kMaximumLifetime = base::Days(1);
- PositionCacheImpl::CacheEntry::CacheEntry(
- const Hash& hash,
- const mojom::Geoposition& position,
- std::unique_ptr<base::OneShotTimer> eviction_timer)
- : hash_(hash),
- position_(position),
- eviction_timer_(std::move(eviction_timer)) {}
- PositionCacheImpl::CacheEntry::~CacheEntry() = default;
- PositionCacheImpl::CacheEntry::CacheEntry(CacheEntry&&) = default;
- PositionCacheImpl::CacheEntry& PositionCacheImpl::CacheEntry::operator=(
- CacheEntry&&) = default;
- // static
- PositionCacheImpl::Hash PositionCacheImpl::MakeKey(const WifiData& wifi_data) {
- // Currently we use only WiFi data and base the key only on the MAC addresses.
- std::u16string key;
- const size_t kCharsPerMacAddress = 6 * 3 + 1; // e.g. "11:22:33:44:55:66|"
- key.reserve(wifi_data.access_point_data.size() * kCharsPerMacAddress);
- const std::u16string separator(u"|");
- for (const auto& access_point_data : wifi_data.access_point_data) {
- key += separator;
- key += access_point_data.mac_address;
- key += separator;
- }
- return key;
- }
- PositionCacheImpl::PositionCacheImpl(const base::TickClock* clock)
- : clock_(clock) {
- net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
- }
- PositionCacheImpl::~PositionCacheImpl() {
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
- }
- void PositionCacheImpl::CachePosition(const WifiData& wifi_data,
- const mojom::Geoposition& position) {
- const Hash key = MakeKey(wifi_data);
- // If the cache is full, remove the oldest entry.
- if (data_.size() == kMaximumSize)
- data_.erase(data_.begin());
- DCHECK_LT(data_.size(), kMaximumSize);
- auto eviction_timer = std::make_unique<base::OneShotTimer>(clock_);
- // Ensure that the entry we're adding will be evicted after kMaximumLifetime.
- // base::Unretained safe because the timer is indirectly owned by |this|.
- eviction_timer->Start(FROM_HERE, kMaximumLifetime,
- base::BindOnce(&PositionCacheImpl::EvictEntry,
- base::Unretained(this), key));
- data_.emplace_back(key, position, std::move(eviction_timer));
- }
- const mojom::Geoposition* PositionCacheImpl::FindPosition(
- const WifiData& wifi_data) const {
- const Hash key = MakeKey(wifi_data);
- auto it = std::find(data_.begin(), data_.end(), key);
- return it == data_.end() ? nullptr : (it->position());
- }
- size_t PositionCacheImpl::GetPositionCacheSize() const {
- return data_.size();
- }
- const mojom::Geoposition& PositionCacheImpl::GetLastUsedNetworkPosition()
- const {
- return last_used_position_;
- }
- void PositionCacheImpl::SetLastUsedNetworkPosition(
- const mojom::Geoposition& position) {
- last_used_position_ = position;
- }
- void PositionCacheImpl::OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType) {
- // OnNetworkChanged is called " when a change occurs to the host
- // computer's hardware or software that affects the route network packets
- // take to any network server.". This means that whatever position we had
- // stored for a wired connection (empty WifiData) could have become stale.
- EvictEntry(MakeKey(WifiData()));
- last_used_position_ = {};
- }
- void PositionCacheImpl::EvictEntry(const Hash& hash) {
- data_.erase(std::remove(data_.begin(), data_.end(), hash), data_.end());
- }
- } // namespace device
|