| 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) {} |
| 35 | 43 |
| 36 NightLightClient::~NightLightClient() {} | 44 NightLightClient::~NightLightClient() {} |
| 37 | 45 |
| 38 void NightLightClient::Start() { | 46 void NightLightClient::Start() { |
| 39 if (!night_light_controller_) { | 47 if (!night_light_controller_) { |
| 40 service_manager::Connector* connector = | 48 service_manager::Connector* connector = |
| 41 content::ServiceManagerConnection::GetForProcess()->GetConnector(); | 49 content::ServiceManagerConnection::GetForProcess()->GetConnector(); |
| 42 connector->BindInterface(ash::mojom::kServiceName, | 50 connector->BindInterface(ash::mojom::kServiceName, |
| 43 &night_light_controller_); | 51 &night_light_controller_); |
| 44 } | 52 } |
| 45 ash::mojom::NightLightClientPtr client; | 53 ash::mojom::NightLightClientPtr client; |
| 46 binding_.Bind(mojo::MakeRequest(&client)); | 54 binding_.Bind(mojo::MakeRequest(&client)); |
| 47 night_light_controller_->SetClient(std::move(client)); | 55 night_light_controller_->SetClient(std::move(client)); |
| 48 } | 56 } |
| 49 | 57 |
| 50 void NightLightClient::OnScheduleTypeChanged( | 58 void NightLightClient::OnScheduleTypeChanged( |
| 51 ash::mojom::NightLightController::ScheduleType new_type) { | 59 ash::mojom::NightLightController::ScheduleType new_type) { |
| 52 if (new_type == | 60 if (new_type != |
| 53 ash::mojom::NightLightController::ScheduleType::kSunsetToSunrise) { | 61 ash::mojom::NightLightController::ScheduleType::kSunsetToSunrise) { |
| 54 // Schedule an immediate request. | |
| 55 using_geoposition_ = true; | |
| 56 ScheduleNextRequest(base::TimeDelta::FromSeconds(0)); | |
| 57 } else { | |
| 58 using_geoposition_ = false; | 62 using_geoposition_ = false; |
| 59 timer_.Stop(); | 63 timer_.Stop(); |
| 64 return; |
| 60 } | 65 } |
| 66 |
| 67 using_geoposition_ = true; |
| 68 // No need to request a new position if we already have a valid one from a |
| 69 // request less than kNextRequestDelayAfterSuccess ago. |
| 70 base::Time now = GetNow(); |
| 71 if ((now - last_successful_geo_request_time_) < |
| 72 kNextRequestDelayAfterSuccess) { |
| 73 // Use the current valid position to update NightLightController. |
| 74 SendCurrentGeoposition(); |
| 75 } |
| 76 |
| 77 // Next request is either immediate or kNextRequestDelayAfterSuccess later |
| 78 // than the last success time, whichever is greater. |
| 79 ScheduleNextRequest(std::max( |
| 80 base::TimeDelta::FromSeconds(0), |
| 81 last_successful_geo_request_time_ + kNextRequestDelayAfterSuccess - now)); |
| 82 } |
| 83 |
| 84 // static |
| 85 base::TimeDelta NightLightClient::GetNextRequestDelayAfterSuccessForTesting() { |
| 86 return kNextRequestDelayAfterSuccess; |
| 61 } | 87 } |
| 62 | 88 |
| 63 void NightLightClient::SetNightLightControllerPtrForTesting( | 89 void NightLightClient::SetNightLightControllerPtrForTesting( |
| 64 ash::mojom::NightLightControllerPtr controller) { | 90 ash::mojom::NightLightControllerPtr controller) { |
| 65 night_light_controller_ = std::move(controller); | 91 night_light_controller_ = std::move(controller); |
| 66 } | 92 } |
| 67 | 93 |
| 68 void NightLightClient::FlushNightLightControllerForTesting() { | 94 void NightLightClient::FlushNightLightControllerForTesting() { |
| 69 night_light_controller_.FlushForTesting(); | 95 night_light_controller_.FlushForTesting(); |
| 70 } | 96 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 83 elapsed > kGeolocationRequestTimeout) { | 109 elapsed > kGeolocationRequestTimeout) { |
| 84 // Don't send invalid positions to ash. | 110 // Don't send invalid positions to ash. |
| 85 // On failure, we schedule another request after the current backoff delay. | 111 // On failure, we schedule another request after the current backoff delay. |
| 86 ScheduleNextRequest(backoff_delay_); | 112 ScheduleNextRequest(backoff_delay_); |
| 87 | 113 |
| 88 // If another failure occurs next, our backoff delay should double. | 114 // If another failure occurs next, our backoff delay should double. |
| 89 backoff_delay_ *= 2; | 115 backoff_delay_ *= 2; |
| 90 return; | 116 return; |
| 91 } | 117 } |
| 92 | 118 |
| 93 night_light_controller_->SetCurrentGeoposition( | 119 last_successful_geo_request_time_ = GetNow(); |
| 94 ash::mojom::SimpleGeoposition::New(position.latitude, | 120 |
| 95 position.longitude)); | 121 latitude_ = position.latitude; |
| 122 longitude_ = position.longitude; |
| 123 SendCurrentGeoposition(); |
| 96 | 124 |
| 97 // On success, reset the backoff delay to its minimum value, and schedule | 125 // On success, reset the backoff delay to its minimum value, and schedule |
| 98 // another request. | 126 // another request. |
| 99 backoff_delay_ = kMinimumDelayAfterFailure; | 127 backoff_delay_ = kMinimumDelayAfterFailure; |
| 100 ScheduleNextRequest(kNextRequestDelayAfterSuccess); | 128 ScheduleNextRequest(kNextRequestDelayAfterSuccess); |
| 101 } | 129 } |
| 102 | 130 |
| 131 base::Time NightLightClient::GetNow() const { |
| 132 return clock_ ? clock_->Now() : base::Time::Now(); |
| 133 } |
| 134 |
| 135 void NightLightClient::SendCurrentGeoposition() { |
| 136 night_light_controller_->SetCurrentGeoposition( |
| 137 ash::mojom::SimpleGeoposition::New(latitude_, longitude_)); |
| 138 } |
| 139 |
| 103 void NightLightClient::ScheduleNextRequest(base::TimeDelta delay) { | 140 void NightLightClient::ScheduleNextRequest(base::TimeDelta delay) { |
| 104 timer_.Start(FROM_HERE, delay, this, &NightLightClient::RequestGeoposition); | 141 timer_.Start(FROM_HERE, delay, this, &NightLightClient::RequestGeoposition); |
| 105 } | 142 } |
| 106 | 143 |
| 107 void NightLightClient::RequestGeoposition() { | 144 void NightLightClient::RequestGeoposition() { |
| 108 provider_.RequestGeolocation( | 145 provider_.RequestGeolocation( |
| 109 kGeolocationRequestTimeout, false /* send_wifi_access_points */, | 146 kGeolocationRequestTimeout, false /* send_wifi_access_points */, |
| 110 false /* send_cell_towers */, | 147 false /* send_cell_towers */, |
| 111 base::Bind(&NightLightClient::OnGeoposition, base::Unretained(this))); | 148 base::Bind(&NightLightClient::OnGeoposition, base::Unretained(this))); |
| 112 } | 149 } |
| OLD | NEW |