Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/night_light/night_light_client.h" | 5 #include "chrome/browser/chromeos/night_light/night_light_client.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 | |
| 7 #include "ash/public/interfaces/constants.mojom.h" | 9 #include "ash/public/interfaces/constants.mojom.h" |
| 10 #include "base/time/clock.h" | |
| 11 #include "base/time/tick_clock.h" | |
| 8 #include "content/public/common/service_manager_connection.h" | 12 #include "content/public/common/service_manager_connection.h" |
| 9 #include "services/service_manager/public/cpp/connector.h" | 13 #include "services/service_manager/public/cpp/connector.h" |
| 10 | 14 |
| 11 namespace { | 15 namespace { |
| 12 | 16 |
| 13 // Delay to wait for a response to our geolocation request, if we get a response | 17 // Delay to wait for a response to our geolocation request, if we get a response |
| 14 // after which, we will consider the request a failure. | 18 // after which, we will consider the request a failure. |
| 15 constexpr base::TimeDelta kGeolocationRequestTimeout = | 19 constexpr base::TimeDelta kGeolocationRequestTimeout = |
| 16 base::TimeDelta::FromSeconds(60); | 20 base::TimeDelta::FromSeconds(60); |
| 17 | 21 |
| 18 // Minimum delay to wait to fire a new request after a previous one failing. | 22 // Minimum delay to wait to fire a new request after a previous one failing. |
| 19 constexpr base::TimeDelta kMinimumDelayAfterFailure = | 23 constexpr base::TimeDelta kMinimumDelayAfterFailure = |
| 20 base::TimeDelta::FromSeconds(60); | 24 base::TimeDelta::FromSeconds(60); |
| 21 | 25 |
| 22 // Delay to wait to fire a new request after a previous one succeeding. | 26 // Delay to wait to fire a new request after a previous one succeeding. |
| 23 constexpr base::TimeDelta kNextRequestDelayAfterSuccess = | 27 constexpr base::TimeDelta kNextRequestDelayAfterSuccess = |
| 24 base::TimeDelta::FromDays(1); | 28 base::TimeDelta::FromDays(1); |
| 25 | 29 |
| 26 } // namespace | 30 } // namespace |
| 27 | 31 |
| 28 NightLightClient::NightLightClient( | 32 NightLightClient::NightLightClient( |
| 29 net::URLRequestContextGetter* url_context_getter) | 33 net::URLRequestContextGetter* url_context_getter, |
| 34 base::TickClock* tick_clock, | |
| 35 base::Clock* clock) | |
| 30 : provider_( | 36 : provider_( |
| 31 url_context_getter, | 37 url_context_getter, |
| 32 chromeos::SimpleGeolocationProvider::DefaultGeolocationProviderURL()), | 38 chromeos::SimpleGeolocationProvider::DefaultGeolocationProviderURL()), |
| 33 binding_(this), | 39 binding_(this), |
| 34 backoff_delay_(kMinimumDelayAfterFailure) {} | 40 backoff_delay_(kMinimumDelayAfterFailure), |
| 41 timer_(tick_clock), | |
| 42 clock_(clock) {} | |
| 43 | |
| 44 NightLightClient::NightLightClient( | |
| 45 net::URLRequestContextGetter* url_context_getter) | |
| 46 : NightLightClient(url_context_getter, nullptr, nullptr) {} | |
| 35 | 47 |
| 36 NightLightClient::~NightLightClient() {} | 48 NightLightClient::~NightLightClient() {} |
| 37 | 49 |
| 38 void NightLightClient::Start() { | 50 void NightLightClient::Start() { |
| 39 if (!night_light_controller_) { | 51 if (!night_light_controller_) { |
| 40 service_manager::Connector* connector = | 52 service_manager::Connector* connector = |
| 41 content::ServiceManagerConnection::GetForProcess()->GetConnector(); | 53 content::ServiceManagerConnection::GetForProcess()->GetConnector(); |
| 42 connector->BindInterface(ash::mojom::kServiceName, | 54 connector->BindInterface(ash::mojom::kServiceName, |
| 43 &night_light_controller_); | 55 &night_light_controller_); |
| 44 } | 56 } |
| 45 ash::mojom::NightLightClientPtr client; | 57 ash::mojom::NightLightClientPtr client; |
| 46 binding_.Bind(mojo::MakeRequest(&client)); | 58 binding_.Bind(mojo::MakeRequest(&client)); |
| 47 night_light_controller_->SetClient(std::move(client)); | 59 night_light_controller_->SetClient(std::move(client)); |
| 48 } | 60 } |
| 49 | 61 |
| 50 void NightLightClient::OnScheduleTypeChanged( | 62 void NightLightClient::OnScheduleTypeChanged( |
| 51 ash::mojom::NightLightController::ScheduleType new_type) { | 63 ash::mojom::NightLightController::ScheduleType new_type) { |
| 52 if (new_type == | 64 if (new_type == |
| 53 ash::mojom::NightLightController::ScheduleType::kSunsetToSunrise) { | 65 ash::mojom::NightLightController::ScheduleType::kSunsetToSunrise) { |
| 54 // Schedule an immediate request. | |
| 55 using_geoposition_ = true; | 66 using_geoposition_ = true; |
| 56 ScheduleNextRequest(base::TimeDelta::FromSeconds(0)); | 67 // No need to request a new position if we already have a valid one from a |
| 68 // request less than kNextRequestDelayAfterSuccess ago. | |
| 69 base::Time now = GetNow(); | |
| 70 if ((now - last_successful_geo_request_time_) < | |
| 71 kNextRequestDelayAfterSuccess) { | |
| 72 // Use the current valid position to update NightLightController. | |
| 73 SendCurrentGeoposition(); | |
| 74 } | |
| 75 | |
| 76 // Next request is either immediate or kNextRequestDelayAfterSuccess later | |
| 77 // than the last success time, whichever is greater. | |
| 78 ScheduleNextRequest(std::max(base::TimeDelta::FromSeconds(0), | |
| 79 last_successful_geo_request_time_ + | |
| 80 kNextRequestDelayAfterSuccess - now)); | |
|
stevenjb
2017/07/01 00:02:35
nit: With the extra complexity here, invert the if
afakhry
2017/07/01 00:26:14
Done.
| |
| 57 } else { | 81 } else { |
| 58 using_geoposition_ = false; | 82 using_geoposition_ = false; |
| 59 timer_.Stop(); | 83 timer_.Stop(); |
| 60 } | 84 } |
| 61 } | 85 } |
| 62 | 86 |
| 87 // static | |
| 88 base::TimeDelta NightLightClient::GetNextRequestDelayAfterSuccessForTesting() { | |
| 89 return kNextRequestDelayAfterSuccess; | |
| 90 } | |
| 91 | |
| 63 void NightLightClient::SetNightLightControllerPtrForTesting( | 92 void NightLightClient::SetNightLightControllerPtrForTesting( |
| 64 ash::mojom::NightLightControllerPtr controller) { | 93 ash::mojom::NightLightControllerPtr controller) { |
| 65 night_light_controller_ = std::move(controller); | 94 night_light_controller_ = std::move(controller); |
| 66 } | 95 } |
| 67 | 96 |
| 68 void NightLightClient::FlushNightLightControllerForTesting() { | 97 void NightLightClient::FlushNightLightControllerForTesting() { |
| 69 night_light_controller_.FlushForTesting(); | 98 night_light_controller_.FlushForTesting(); |
| 70 } | 99 } |
| 71 | 100 |
| 72 void NightLightClient::OnGeoposition(const chromeos::Geoposition& position, | 101 void NightLightClient::OnGeoposition(const chromeos::Geoposition& position, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 83 elapsed > kGeolocationRequestTimeout) { | 112 elapsed > kGeolocationRequestTimeout) { |
| 84 // Don't send invalid positions to ash. | 113 // Don't send invalid positions to ash. |
| 85 // On failure, we schedule another request after the current backoff delay. | 114 // On failure, we schedule another request after the current backoff delay. |
| 86 ScheduleNextRequest(backoff_delay_); | 115 ScheduleNextRequest(backoff_delay_); |
| 87 | 116 |
| 88 // If another failure occurs next, our backoff delay should double. | 117 // If another failure occurs next, our backoff delay should double. |
| 89 backoff_delay_ *= 2; | 118 backoff_delay_ *= 2; |
| 90 return; | 119 return; |
| 91 } | 120 } |
| 92 | 121 |
| 93 night_light_controller_->SetCurrentGeoposition( | 122 last_successful_geo_request_time_ = GetNow(); |
| 94 ash::mojom::SimpleGeoposition::New(position.latitude, | 123 |
| 95 position.longitude)); | 124 latitude_ = position.latitude; |
| 125 longitude_ = position.longitude; | |
| 126 SendCurrentGeoposition(); | |
| 96 | 127 |
| 97 // On success, reset the backoff delay to its minimum value, and schedule | 128 // On success, reset the backoff delay to its minimum value, and schedule |
| 98 // another request. | 129 // another request. |
| 99 backoff_delay_ = kMinimumDelayAfterFailure; | 130 backoff_delay_ = kMinimumDelayAfterFailure; |
| 100 ScheduleNextRequest(kNextRequestDelayAfterSuccess); | 131 ScheduleNextRequest(kNextRequestDelayAfterSuccess); |
| 101 } | 132 } |
| 102 | 133 |
| 134 base::Time NightLightClient::GetNow() const { | |
| 135 return clock_ ? clock_->Now() : base::Time::Now(); | |
| 136 } | |
| 137 | |
| 138 void NightLightClient::SendCurrentGeoposition() { | |
| 139 night_light_controller_->SetCurrentGeoposition( | |
| 140 ash::mojom::SimpleGeoposition::New(latitude_, longitude_)); | |
| 141 } | |
| 142 | |
| 103 void NightLightClient::ScheduleNextRequest(base::TimeDelta delay) { | 143 void NightLightClient::ScheduleNextRequest(base::TimeDelta delay) { |
| 104 timer_.Start(FROM_HERE, delay, this, &NightLightClient::RequestGeoposition); | 144 timer_.Start(FROM_HERE, delay, this, &NightLightClient::RequestGeoposition); |
| 105 } | 145 } |
| 106 | 146 |
| 107 void NightLightClient::RequestGeoposition() { | 147 void NightLightClient::RequestGeoposition() { |
| 108 provider_.RequestGeolocation( | 148 provider_.RequestGeolocation( |
| 109 kGeolocationRequestTimeout, false /* send_wifi_access_points */, | 149 kGeolocationRequestTimeout, false /* send_wifi_access_points */, |
| 110 false /* send_cell_towers */, | 150 false /* send_cell_towers */, |
| 111 base::Bind(&NightLightClient::OnGeoposition, base::Unretained(this))); | 151 base::Bind(&NightLightClient::OnGeoposition, base::Unretained(this))); |
| 112 } | 152 } |
| OLD | NEW |