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 SERVICES_DEVICE_GEOLOCATION_PUBLIC_IP_ADDRESS_LOCATION_NOTIFIER_H_ 6 #define SERVICES_DEVICE_GEOLOCATION_PUBLIC_IP_ADDRESS_LOCATION_NOTIFIER_H_ 7 8 #include <memory> 9 10 #include "base/callback.h" 11 #include "base/callback_list.h" 12 #include "base/cancelable_callback.h" 13 #include "base/macros.h" 14 #include "base/optional.h" 15 #include "base/time/time.h" 16 #include "net/traffic_annotation/network_traffic_annotation.h" 17 #include "services/device/geolocation/geolocation_provider.h" 18 #include "services/device/geolocation/network_location_request.h" 19 #include "services/device/public/mojom/geoposition.mojom.h" 20 #include "services/network/public/cpp/network_connection_tracker.h" 21 22 namespace device { 23 24 class NetworkLocationRequest; 25 struct WifiData; 26 27 // Provides subscribers with updates of the device's approximate geographic 28 // location inferred from its publicly-visible IP address. 29 // Sequencing: 30 // * Must be created, used, and destroyed on the same sequence. 31 class PublicIpAddressLocationNotifier 32 : public network::NetworkConnectionTracker::NetworkConnectionObserver { 33 public: 34 // Creates a notifier that uses the specified Google |api_key| and 35 // |url_loader_factory| for network location requests. 36 PublicIpAddressLocationNotifier( 37 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, 38 network::NetworkConnectionTracker* network_connection_tracker, 39 const std::string& api_key); 40 ~PublicIpAddressLocationNotifier() override; 41 42 using QueryNextPositionCallback = 43 base::OnceCallback<void(const mojom::Geoposition&)>; 44 45 // Requests a callback with the next Geoposition obtained later than 46 // |time_of_prev_position|. 47 // Specifically: 48 // * If a position has been obtained subsequent to |time_of_prev_position|, 49 // returns it. 50 // * Otherwise, returns an updated position once a network change has 51 // occurred. 52 // * Note that it is possible for |callback| to never be called if no network 53 // change ever occurs after |time_of_prev_position|. 54 void QueryNextPosition(base::Time time_of_prev_position, 55 const net::PartialNetworkTrafficAnnotationTag& tag, 56 QueryNextPositionCallback callback); 57 58 private: 59 // Sequence checker for all methods. 60 SEQUENCE_CHECKER(sequence_checker_); 61 62 // NetworkConnectionTracker::NetworkConnectionObserver: 63 // Network change notifications tend to come in a cluster in a short time, so 64 // this just sets a task to run ReactToNetworkChange after a short time. 65 void OnConnectionChanged(network::mojom::ConnectionType type) override; 66 67 // Actually react to a network change, starting a network geolocation request 68 // if any clients are waiting. 69 void ReactToNetworkChange(); 70 71 // Creates |network_location_request_| and starts the network request, which 72 // will invoke OnNetworkLocationResponse when done. 73 void MakeNetworkLocationRequest(); 74 75 // Completion callback for network_location_request_. 76 void OnNetworkLocationResponse(const mojom::Geoposition& position, 77 bool server_error, 78 const WifiData& wifi_data); 79 80 // Cancelable closure to absorb overlapping delayed calls to 81 // ReactToNetworkChange. 82 base::CancelableOnceClosure react_to_network_change_closure_; 83 84 // Whether we have been notified of a network change since the last network 85 // location request was sent. 86 bool network_changed_since_last_request_; 87 88 // The geoposition as of the latest network change, if it has been obtained. 89 base::Optional<mojom::Geoposition> latest_geoposition_; 90 91 // Google API key for network geolocation requests. 92 const std::string api_key_; 93 94 // SharedURLLoaderFactory for network geolocation requests. 95 const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; 96 97 // Used to listen to network connection changes. 98 // Must outlive this object. 99 network::NetworkConnectionTracker* network_connection_tracker_; 100 101 // Used to make calls to the Maps geolocate API. 102 // Empty unless a call is currently in progress. 103 std::unique_ptr<NetworkLocationRequest> network_location_request_; 104 105 // Clients waiting for an updated geoposition. 106 std::vector<QueryNextPositionCallback> callbacks_; 107 108 // The most recent PartialNetworkTrafficAnnotationTag provided by a client. 109 std::unique_ptr<const net::PartialNetworkTrafficAnnotationTag> 110 network_traffic_annotation_tag_; 111 112 // Weak references to |this| for posted tasks. 113 base::WeakPtrFactory<PublicIpAddressLocationNotifier> weak_ptr_factory_{this}; 114 115 DISALLOW_COPY_AND_ASSIGN(PublicIpAddressLocationNotifier); 116 }; 117 118 } // namespace device 119 120 #endif // SERVICES_DEVICE_GEOLOCATION_PUBLIC_IP_ADDRESS_LOCATION_NOTIFIER_H_ 121