| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/system/time/calendar_event_fetch.h" |
| |
| #include "ash/calendar/calendar_client.h" |
| #include "ash/calendar/calendar_controller.h" |
| #include "ash/glanceables/post_login_glanceables_metrics_recorder.h" |
| #include "ash/shell.h" |
| #include "ash/system/time/calendar_metrics.h" |
| #include "ash/system/time/calendar_utils.h" |
| #include "base/check.h" |
| #include "base/functional/bind.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/time/tick_clock.h" |
| #include "base/time/time.h" |
| #include "google_apis/calendar/calendar_api_requests.h" |
| |
| #undef ENABLED_VLOG_LEVEL |
| #define ENABLED_VLOG_LEVEL 1 |
| |
| namespace ash { |
| |
| CalendarEventFetch::CalendarEventFetch( |
| const base::Time& start_of_month, |
| FetchCompleteCallback complete_callback, |
| FetchInternalErrorCallback internal_error_callback, |
| const base::TickClock* tick_clock) |
| : start_of_month_(start_of_month), |
| time_range_(calendar_utils::GetFetchStartEndTimes(start_of_month)), |
| complete_callback_(std::move(complete_callback)), |
| internal_error_callback_(std::move(internal_error_callback)), |
| fetch_start_time_(base::TimeTicks::Now()), |
| timeout_(tick_clock), |
| calendar_id_(google_apis::calendar::kPrimaryCalendarId) { |
| SendFetchRequest(); |
| Shell::Get() |
| ->post_login_glanceables_metrics_reporter() |
| ->RecordCalendarFetch(); |
| } |
| |
| CalendarEventFetch::CalendarEventFetch( |
| const base::Time& start_of_month, |
| FetchCompleteCallback complete_callback, |
| FetchInternalErrorCallback internal_error_callback, |
| const base::TickClock* tick_clock, |
| const std::string& calendar_id, |
| const std::string& calendar_color_id) |
| : start_of_month_(start_of_month), |
| time_range_(calendar_utils::GetFetchStartEndTimes(start_of_month)), |
| complete_callback_(std::move(complete_callback)), |
| internal_error_callback_(std::move(internal_error_callback)), |
| fetch_start_time_(base::TimeTicks::Now()), |
| timeout_(tick_clock), |
| calendar_id_(calendar_id), |
| calendar_color_id_(calendar_color_id) { |
| SendFetchRequestByCalendarId(); |
| Shell::Get() |
| ->post_login_glanceables_metrics_reporter() |
| ->RecordCalendarFetch(); |
| } |
| |
| CalendarEventFetch::~CalendarEventFetch() = default; |
| |
| void CalendarEventFetch::Cancel() { |
| std::move(cancel_closure_).Run(); |
| } |
| |
| void CalendarEventFetch::SendFetchRequest() { |
| if (cancel_closure_) |
| Cancel(); |
| |
| CalendarClient* client = Shell::Get()->calendar_controller()->GetClient(); |
| CHECK(client); |
| |
| cancel_closure_ = |
| client->GetEventList(base::BindOnce(&CalendarEventFetch::OnResultReceived, |
| weak_factory_.GetWeakPtr()), |
| time_range_.first, time_range_.second); |
| CHECK(cancel_closure_); |
| |
| timeout_.Start(FROM_HERE, calendar_utils::kCalendarDataFetchTimeout, |
| base::BindOnce(&CalendarEventFetch::OnTimeout, |
| weak_factory_.GetWeakPtr())); |
| } |
| |
| void CalendarEventFetch::SendFetchRequestByCalendarId() { |
| if (cancel_closure_) { |
| Cancel(); |
| } |
| |
| CalendarClient* client = Shell::Get()->calendar_controller()->GetClient(); |
| CHECK(client); |
| |
| cancel_closure_ = client->GetEventList( |
| base::BindOnce(&CalendarEventFetch::OnResultReceived, |
| weak_factory_.GetWeakPtr()), |
| time_range_.first, time_range_.second, calendar_id_, calendar_color_id_); |
| CHECK(cancel_closure_); |
| |
| timeout_.Start(FROM_HERE, calendar_utils::kCalendarDataFetchTimeout, |
| base::BindOnce(&CalendarEventFetch::OnTimeout, |
| weak_factory_.GetWeakPtr())); |
| } |
| |
| void CalendarEventFetch::OnResultReceived( |
| google_apis::ApiErrorCode error, |
| std::unique_ptr<google_apis::calendar::EventList> events) { |
| // Cancel timeout timer. |
| timeout_.Stop(); |
| |
| calendar_metrics::RecordEventListFetchDuration(base::TimeTicks::Now() - |
| fetch_start_time_); |
| calendar_metrics::RecordEventListFetchTimeout(false); |
| |
| // IMPORTANT: 'this' is NOT safe to use after `complete_callback_` has been |
| // executed, as the last thing it does is destroy its |
| // std::unique_ptr<CalendarEventFetch> to this object. |
| std::move(complete_callback_) |
| .Run(start_of_month_, calendar_id_, error, events.get()); |
| } |
| |
| void CalendarEventFetch::OnTimeout() { |
| calendar_metrics::RecordEventListFetchTimeout(true); |
| |
| // IMPORTANT: 'this' is NOT safe to use after `internal_error_callback_` has |
| // been executed, as the last thing it does is destroy its |
| // std::unique_ptr<CalendarEventFetch> to this object. |
| std::move(internal_error_callback_) |
| .Run(start_of_month_, calendar_id_, |
| CalendarEventFetchInternalErrorCode::kTimeout); |
| } |
| |
| } // namespace ash |