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
|