File: chrome_tasks_delegate.cc

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 (179 lines) | stat: -rw-r--r-- 6,954 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
// 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.

#include "chrome/browser/ash/api/tasks/chrome_tasks_delegate.h"

#include <memory>
#include <string>

#include "ash/api/tasks/tasks_client.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ash/api/tasks/tasks_client_impl.h"
#include "components/signin/public/base/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/user_manager/user_manager.h"
#include "google_apis/common/auth_service.h"
#include "google_apis/common/request_sender.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

namespace ash::api {

namespace {

// TODO(b/306433892): Add policy and document it here or explain why we did not
// create a policy.
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("tasks_integration",
                                        R"(
        semantics {
          sender: "Chrome tasks delegate"
          description: "Provides ChromeOS users quick access to their task "
                       "lists and tasks without opening the app or website."
          trigger: "User opens a panel in Focus Mode."
          data: "The request is authenticated with an OAuth2 access token "
                "identifying the Google account."
          internal {
            contacts {
              email: "benbecker@google.com"
            }
            contacts {
              email: "chromeos-wms@google.com"
            }
          }
          user_data {
            type: ACCESS_TOKEN
          }
          destination: GOOGLE_OWNED_SERVICE
          last_reviewed: "2023-11-10"
        }
        policy {
          cookies_allowed: NO
          setting: "This feature cannot be disabled in settings."
          chrome_policy {
            ContextualGoogleIntegrationsEnabled {
              ContextualGoogleIntegrationsEnabled: false
            }
          }
        }
    )");

// Passed to the active user's client in `ChromeTasksDelegate` so that it can
// generate a `google_apis::RequestSender` instance to use whenever it is making
// a call to the Google Tasks API. The `scopes` are used for authorizing the
// RequestSender instance and the `traffic_annotation_tag` documents the network
// request for system admins and regulators. The client requests this callback
// on creation so that it can use different callbacks to create dummy auth
// services in testing situations (See
// chrome/browser/ash/api/tasks/tasks_client_impl_unittest.cc).
std::unique_ptr<google_apis::RequestSender> CreateRequestSenderForClient(
    const std::vector<std::string>& scopes,
    const net::NetworkTrafficAnnotationTag& traffic_annotation_tag) {
  Profile* profile = ProfileManager::GetActiveUserProfile();
  signin::IdentityManager* identity_manager =
      IdentityManagerFactory::GetForProfile(profile);
  const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
      profile->GetURLLoaderFactory();

  std::unique_ptr<google_apis::AuthService> auth_service =
      std::make_unique<google_apis::AuthService>(
          identity_manager,
          identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin),
          url_loader_factory, scopes);
  return std::make_unique<google_apis::RequestSender>(
      std::move(auth_service), url_loader_factory,
      base::ThreadPool::CreateSequencedTaskRunner(
          {base::MayBlock(),
           /* `USER_VISIBLE` is because the requested/returned data is visible
              to the user on System UI surfaces. */
           base::TaskPriority::USER_VISIBLE,
           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}),
      /*custom_user_agent=*/std::string(), traffic_annotation_tag);
}

}  // namespace

ChromeTasksDelegate::ChromeTasksDelegate() = default;

ChromeTasksDelegate::~ChromeTasksDelegate() = default;

void ChromeTasksDelegate::UpdateClientForProfileSwitch(
    const AccountId& account_id) {
  // Cleanup before switching clients.
  if (active_account_id_.is_valid()) {
    TasksClientImpl* client = GetActiveAccountClient();
    CHECK(client);
    client->InvalidateCache();
  }

  // Do not create a client for guest profiles and don't create a new client for
  // an account that has already been registered.
  if (user_manager::UserManager::IsInitialized() &&
      !user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
    auto& client = clients_[account_id];
    if (!client) {
      client = std::make_unique<TasksClientImpl>(
          ProfileHelper::Get()->GetProfileByAccountId(account_id),
          base::BindRepeating(&CreateRequestSenderForClient),
          kTrafficAnnotation);
    }
  }

  active_account_id_ = account_id;
}

void ChromeTasksDelegate::GetTaskLists(
    bool force_fetch,
    TasksClient::GetTaskListsCallback callback) {
  CHECK(active_account_id_.is_valid());
  TasksClientImpl* client = GetActiveAccountClient();
  CHECK(client);
  client->GetTaskLists(force_fetch, std::move(callback));
}

void ChromeTasksDelegate::GetTasks(const std::string& task_list_id,
                                   bool force_fetch,
                                   TasksClient::GetTasksCallback callback) {
  CHECK(active_account_id_.is_valid());
  TasksClientImpl* client = GetActiveAccountClient();
  CHECK(client);
  client->GetTasks(task_list_id, force_fetch, std::move(callback));
}

void ChromeTasksDelegate::AddTask(const std::string& task_list_id,
                                  const std::string& title,
                                  TasksClient::OnTaskSavedCallback callback) {
  CHECK(active_account_id_.is_valid());
  TasksClientImpl* client = GetActiveAccountClient();
  CHECK(client);
  client->AddTask(task_list_id, title, std::move(callback));
}

void ChromeTasksDelegate::UpdateTask(
    const std::string& task_list_id,
    const std::string& task_id,
    const std::string& title,
    bool completed,
    TasksClient::OnTaskSavedCallback callback) {
  CHECK(active_account_id_.is_valid());
  TasksClientImpl* client = GetActiveAccountClient();
  CHECK(client);
  client->UpdateTask(task_list_id, task_id, title, completed,
                     std::move(callback));
}

TasksClientImpl* ChromeTasksDelegate::GetActiveAccountClient() const {
  const auto iter = clients_.find(active_account_id_);
  return iter != clients_.end() ? iter->second.get() : nullptr;
}

}  // namespace ash::api