File: tasks_client_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (290 lines) | stat: -rw-r--r-- 12,370 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_API_TASKS_TASKS_CLIENT_IMPL_H_
#define CHROME_BROWSER_ASH_API_TASKS_TASKS_CLIENT_IMPL_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "ash/api/tasks/tasks_client.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/types/expected.h"
#include "google_apis/tasks/tasks_api_requests.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/base/models/list_model.h"

class Profile;

namespace base {
class Time;
}  // namespace base

namespace google_apis {
class RequestSender;
namespace tasks {
class TaskLists;
class Tasks;
}  // namespace tasks
}  // namespace google_apis

namespace ash::api {

struct Task;
struct TaskList;

// Provides implementation for `TasksClient`. Responsible for communication with
// Google Tasks API.
class TasksClientImpl : public TasksClient {
 public:
  // Provides an instance of `google_apis::RequestSender` for the client.
  using CreateRequestSenderCallback =
      base::RepeatingCallback<std::unique_ptr<google_apis::RequestSender>(
          const std::vector<std::string>& scopes,
          const net::NetworkTrafficAnnotationTag& traffic_annotation_tag)>;

  TasksClientImpl(
      Profile* profile,
      const CreateRequestSenderCallback& create_request_sender_callback,
      net::NetworkTrafficAnnotationTag traffic_annotation_tag);
  TasksClientImpl(const TasksClientImpl&) = delete;
  TasksClientImpl& operator=(const TasksClientImpl&) = delete;
  ~TasksClientImpl() override;

  // TasksClient:
  bool IsDisabledByAdmin() const override;
  const ui::ListModel<api::TaskList>* GetCachedTaskLists() override;
  void GetTaskLists(bool force_fetch,
                    TasksClient::GetTaskListsCallback callback) override;
  const ui::ListModel<api::Task>* GetCachedTasksInTaskList(
      const std::string& task_list_id) override;
  void GetTasks(const std::string& task_list_id,
                bool force_fetch,
                TasksClient::GetTasksCallback callback) override;
  void MarkAsCompleted(const std::string& task_list_id,
                       const std::string& task_id,
                       bool completed) override;
  void AddTask(const std::string& task_list_id,
               const std::string& title,
               TasksClient::OnTaskSavedCallback callback) override;
  void UpdateTask(const std::string& task_list_id,
                  const std::string& task_id,
                  const std::string& title,
                  bool completed,
                  TasksClient::OnTaskSavedCallback callback) override;
  void InvalidateCache() override;
  std::optional<base::Time> GetTasksLastUpdateTime(
      const std::string& task_list_id) const override;
  void OnGlanceablesBubbleClosed(base::OnceClosure callback) override;

  using TaskListsRequestCallback =
      base::RepeatingCallback<void(const std::string& page_token)>;
  void set_task_lists_request_callback_for_testing(
      const TaskListsRequestCallback& callback) {
    task_lists_request_callback_ = callback;
  }

  using TasksRequestCallback =
      base::RepeatingCallback<void(const std::string& task_list_id,
                                   const std::string& page_token)>;
  void set_tasks_request_callback_for_testing(
      const TasksRequestCallback& callback) {
    tasks_request_callback_ = callback;
  }

 private:
  enum class FetchStatus { kNotFresh, kRefreshing, kFresh };

  // A structure that keeps track of fetch status and list of pending
  // callbacks for a task lists fetch request.
  struct TaskListsFetchState {
    TaskListsFetchState();
    ~TaskListsFetchState();

    FetchStatus status = FetchStatus::kNotFresh;
    // Callbacks to be called when all task lists get fetched using tasks API.
    // Should be non-empty if a task lists fetch is in progress.
    std::vector<TasksClient::GetTaskListsCallback> callbacks;
  };

  // A structure that keeps track of fetch status and list of pending callbacks
  // for a single tasks in a task list fetch request.
  struct TasksFetchState {
    TasksFetchState();
    ~TasksFetchState();

    FetchStatus status = FetchStatus::kNotFresh;

    // The last time that the tasks were fetched and the status became kFresh.
    std::optional<base::Time> last_updated_time = std::nullopt;

    // Callbacks to be called when all tasks in a task list get fetched using
    // tasks API.
    // Should be non-empty if a tasks fetch for the target task list is in
    // progress.
    std::vector<TasksClient::GetTasksCallback> callbacks;
  };

  // Fetches one page of task lists data.
  // `page_token`  - token specifying the result page to return, comes from the
  //                 previous fetch request. Use an empty string to fetch the
  //                 first page.
  // `page_number` - 1-based page number of this fetch request. Used for UMA
  //                 to track the total number of pages needed to fetch.
  // `accumulated_raw_task_lists` - The list of task lists accumulated from
  //                                different task lists pages.
  void FetchTaskListsPage(
      const std::string& page_token,
      int page_number,
      std::vector<std::unique_ptr<google_apis::tasks::TaskList>>
          accumulated_raw_task_lists);

  // Callback for `FetchTaskListsPage()`. Transforms fetched items to
  // ash-friendly types. If `next_page_token()` in the `result` is not empty -
  // calls another `FetchTaskListsPage()`, otherwise runs
  // `RunGetTaskListsCallbacks()`.
  void OnTaskListsPageFetched(
      const base::Time& request_start_time,
      int page_number,
      std::vector<std::unique_ptr<google_apis::tasks::TaskList>>
          accumulated_raw_task_lists,
      base::expected<std::unique_ptr<google_apis::tasks::TaskLists>,
                     google_apis::ApiErrorCode> result);

  // Fetches one page of tasks data.
  // `task_list_id`          - task list identifier.
  // `page_token`            - token specifying the result page to return, comes
  //                           from the previous fetch request. Use an empty
  //                           string to fetch the first page.
  // `page_number`           - 1-based page number of this fetch request. Used
  //                           for UMA to track the total number of pages needed
  //                           to fetch.
  // `accumulated_raw_tasks` - in contrast to the task lists conversion logic,
  //                           tasks can't be converted independently on every
  //                           single page response (subtasks could go first,
  //                           but their parent tasks will be on the next page).
  //                           This parameter helps to accumulate all of them
  //                           first and then do the conversion once the last
  //                           page is fetched.
  void FetchTasksPage(const std::string& task_list_id,
                      const std::string& page_token,
                      int page_number,
                      std::vector<std::unique_ptr<google_apis::tasks::Task>>
                          accumulated_raw_tasks);

  // Callback for `FetchTasksPage()`. Transforms fetched items to ash-friendly
  // types. If `next_page_token()` in the `result` is not empty - calls another
  // `FetchTasksPage()`, otherwise runs `RunGetTasksCallbacks()`.
  void OnTasksPageFetched(
      const std::string& task_list_id,
      std::vector<std::unique_ptr<google_apis::tasks::Task>>
          accumulated_raw_tasks,
      const base::Time& request_start_time,
      int page_number,
      base::expected<std::unique_ptr<google_apis::tasks::Tasks>,
                     google_apis::ApiErrorCode> result);

  // Callback for `MarkAsCompleted()` request. Does not removes the task from
  // `tasks_in_task_lists_` as it will be cleared by
  // `OnGlanceablesBubbleClosed`.
  void OnMarkedAsCompleted(
      const base::Time& request_start_time,
      base::RepeatingClosure on_done,
      base::expected<std::unique_ptr<google_apis::tasks::Task>,
                     google_apis::ApiErrorCode> result);

  // Done callback for `AddTask()` request.
  // `task_list_id`       - id of the task list used in the request.
  // `request_start_time` - start time of the request to measure latency.
  // `callback`           - done callback passed from `AddTask`.
  // `result`             - newly created task or HTTP error.
  void OnTaskAdded(const std::string& task_list_id,
                   const base::Time& request_start_time,
                   TasksClient::OnTaskSavedCallback callback,
                   base::expected<std::unique_ptr<google_apis::tasks::Task>,
                                  google_apis::ApiErrorCode> result);

  // Done callback for `UpdateTask()` request.
  // `task_list_id`       - id of the task list used in the request.
  // `request_start_time` - start time of the request to measure latency.
  // `callback`           - done callback passed from `UpdateTask`.
  // `result`             - updated task or HTTP error.
  void OnTaskUpdated(const std::string& task_list_id,
                     const base::Time& request_start_time,
                     TasksClient::OnTaskSavedCallback callback,
                     base::expected<std::unique_ptr<google_apis::tasks::Task>,
                                    google_apis::ApiErrorCode> result);

  // To be called when requests to get user's task lists complete.
  // It sets the task lists fetch status to `final_fetch_status`, and runs all
  // pending callbacks in `task_lists_fetch_state_`. `http_error` will have a
  // value from the Google Tasks API request.
  void RunGetTaskListsCallbacks(
      FetchStatus final_fetch_status,
      std::optional<google_apis::ApiErrorCode> http_error,
      std::vector<std::unique_ptr<google_apis::tasks::TaskList>>
          accumulated_raw_task_lists);

  // To be called when requests to get tasks in the task list identified by
  // `task_list_id` complete. It sets fetch status for the task list fetch to
  // `final_fetch_status`, and runs all pending callbacks for the task list
  // (kept in `tasks_fetch_state_` map). The callbacks are run with `tasks`.
  void RunGetTasksCallbacks(
      const std::string& task_list_id,
      FetchStatus final_fetch_status,
      std::optional<google_apis::ApiErrorCode> http_error,
      std::vector<std::unique_ptr<google_apis::tasks::Task>>
          accumulated_raw_tasks);

  // A map of `task_list_id` to a set of `task_id` that are pending to be
  // completed.
  std::map<std::string, std::set<std::string>> pending_completed_tasks_;

  // Returns lazily initialized `request_sender_`.
  google_apis::RequestSender* GetRequestSender();

  // The profile for which this instance was created.
  const raw_ptr<Profile> profile_;

  // Callback passed from `GlanceablesKeyedService` that creates
  // `request_sender_`.
  const CreateRequestSenderCallback create_request_sender_callback_;

  // Helper class that sends requests, handles retries and authentication.
  std::unique_ptr<google_apis::RequestSender> request_sender_;

  // The current fetch state for the users task lists.
  TaskListsFetchState task_lists_fetch_state_;

  // All available task lists.
  ui::ListModel<TaskList> task_lists_;

  // All available tasks grouped by task list id.
  std::map<std::string, ui::ListModel<Task>> tasks_in_task_lists_;

  // Map that contains fetch states for tasks requests from different task
  // lists. Mapped by the task list id.
  std::map<std::string, std::unique_ptr<TasksFetchState>> tasks_fetch_state_;

  // Stub tasks list model that can be used to return an empty task list to
  // `GetTasks()` requests.
  ui::ListModel<Task> stub_task_list_;

  // Callbacks invoked whenever a tasks API request is made. Used primarily
  // in tests.
  TaskListsRequestCallback task_lists_request_callback_;
  TasksRequestCallback tasks_request_callback_;

  const net::NetworkTrafficAnnotationTag traffic_annotation_tag_;

  base::WeakPtrFactory<TasksClientImpl> weak_factory_{this};
};

}  // namespace ash::api

#endif  // CHROME_BROWSER_ASH_API_TASKS_TASKS_CLIENT_IMPL_H_