1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROMEOS_COMPONENTS_TETHER_TOP_LEVEL_HOST_SCAN_CACHE_H_
6 #define CHROMEOS_COMPONENTS_TETHER_TOP_LEVEL_HOST_SCAN_CACHE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <unordered_map>
11 #include <unordered_set>
12 
13 #include "base/gtest_prod_util.h"
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/timer/timer.h"
17 #include "chromeos/components/tether/host_scan_cache.h"
18 
19 namespace chromeos {
20 
21 namespace tether {
22 
23 class ActiveHost;
24 class PersistentHostScanCache;
25 class TimerFactory;
26 
27 // HostScanCache implementation which interfaces with the network stack as well
28 // as storing scanned device properties persistently and recovering stored
29 // properties after a browser crash. When SetHostScanResult() is called,
30 // TopLevelHostScanCache starts a timer which automatically removes scan results
31 // after |kNumMinutesBeforeCacheEntryExpires| minutes.
32 class TopLevelHostScanCache : public HostScanCache {
33  public:
34   // The number of minutes that a cache entry is considered to be valid before
35   // it is removed from the cache. Very old host scan results are removed from
36   // the cache because the results contain properties such as battery percentage
37   // and signal strength which are ephemeral in nature. However, this timeout
38   // value is chosen to be rather long because we assume that most users usually
39   // do not move their Chrome OS devices physically away from their potential
40   // tether host devices while in use. Note that when network settings UI is
41   // opened, a new scan will be triggered, and any devices currently in the
42   // cache which are not discovered during the scan are removed.
43   static constexpr int kNumMinutesBeforeCacheEntryExpires = 120;
44 
45   TopLevelHostScanCache(std::unique_ptr<TimerFactory> timer_factory,
46                         ActiveHost* active_host,
47                         HostScanCache* network_host_scan_cache,
48                         PersistentHostScanCache* persistent_host_scan_cache);
49   ~TopLevelHostScanCache() override;
50 
51   // HostScanCache:
52   void SetHostScanResult(const HostScanCacheEntry& entry) override;
53   bool ExistsInCache(const std::string& tether_network_guid) override;
54   std::unordered_set<std::string> GetTetherGuidsInCache() override;
55   bool DoesHostRequireSetup(const std::string& tether_network_guid) override;
56 
57  protected:
58   bool RemoveHostScanResultImpl(
59       const std::string& tether_network_guid) override;
60 
61  private:
62   friend class TopLevelHostScanCacheTest;
63 
64   void InitializeFromPersistentCache();
65   void StartTimer(const std::string& tether_network_guid);
66   void OnTimerFired(const std::string& tether_network_guid);
67 
68   std::unique_ptr<TimerFactory> timer_factory_;
69   ActiveHost* active_host_;
70   HostScanCache* network_host_scan_cache_;
71   PersistentHostScanCache* persistent_host_scan_cache_;
72 
73   bool is_initializing_;
74 
75   // Maps from the Tether network GUID to a Timer object. While a scan result is
76   // active in the cache, the corresponding Timer object starts running; if the
77   // timer fires, the result is removed (unless it corresponds to the active
78   // host).
79   std::unordered_map<std::string, std::unique_ptr<base::OneShotTimer>>
80       tether_guid_to_timer_map_;
81   base::WeakPtrFactory<TopLevelHostScanCache> weak_ptr_factory_{this};
82 
83   DISALLOW_COPY_AND_ASSIGN(TopLevelHostScanCache);
84 };
85 
86 }  // namespace tether
87 
88 }  // namespace chromeos
89 
90 #endif  // CHROMEOS_COMPONENTS_TETHER_TOP_LEVEL_HOST_SCAN_CACHE_H_
91