blob: 5c931a604519aa2e9e3c4d22ca25bb9ce7265c1c [file] [log] [blame]
// 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.
#ifndef SERVICES_DEVICE_GEOLOCATION_POSITION_CACHE_IMPL_H_
#define SERVICES_DEVICE_GEOLOCATION_POSITION_CACHE_IMPL_H_
#include <memory>
#include <utility>
#include <vector>
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/network_change_notifier.h"
#include "services/device/geolocation/position_cache.h"
#include "services/device/public/mojom/geoposition.mojom.h"
namespace base {
class TickClock;
} // namespace base
namespace device {
class PositionCacheImpl
: public PositionCache,
public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
// The maximum size of the cache of positions.
static const size_t kMaximumSize;
// The maximum time an entry can reside in cache before forced eviction.
// This is to ensure the user's location cannot be tracked arbitrarily far
// back in history.
static const base::TimeDelta kMaximumLifetime;
// |clock| is used to measure time left until kMaximumLifetime.
explicit PositionCacheImpl(const base::TickClock* clock);
~PositionCacheImpl() override;
void CachePosition(const WifiData& wifi_data,
const mojom::Geoposition& position) override;
const mojom::Geoposition* FindPosition(
const WifiData& wifi_data) const override;
size_t GetPositionCacheSize() const override;
const mojom::Geoposition& GetLastUsedNetworkPosition() const override;
void SetLastUsedNetworkPosition(const mojom::Geoposition& position) override;
// net::NetworkChangeNotifier::NetworkChangeObserver
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override;
private:
// In order to avoid O(N) comparisons while searching for the right WifiData,
// we hash the contents of those objects and use the hashes as cache keys.
using Hash = base::string16;
class CacheEntry {
public:
CacheEntry(const Hash& hash,
const mojom::Geoposition& position,
std::unique_ptr<base::OneShotTimer> eviction_timer);
~CacheEntry();
CacheEntry(CacheEntry&&);
CacheEntry& operator=(CacheEntry&&);
inline bool operator==(const Hash& hash) const { return hash_ == hash; }
const mojom::Geoposition* position() const { return &position_; }
private:
Hash hash_;
mojom::Geoposition position_;
std::unique_ptr<base::OneShotTimer> eviction_timer_;
DISALLOW_COPY_AND_ASSIGN(CacheEntry);
};
static Hash MakeKey(const WifiData& wifi_data);
void EvictEntry(const Hash& hash);
const base::TickClock* clock_;
std::vector<CacheEntry> data_;
mojom::Geoposition last_used_position_;
DISALLOW_COPY_AND_ASSIGN(PositionCacheImpl);
};
} // namespace device
#endif // SERVICES_DEVICE_GEOLOCATION_POSITION_CACHE_IMPL_H_