account_manager_facade_impl.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/account_manager_core/account_manager_facade_impl.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/bind.h"
  10. #include "base/callback_helpers.h"
  11. #include "base/check.h"
  12. #include "base/logging.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/metrics/histogram_functions.h"
  16. #include "base/notreached.h"
  17. #include "base/strings/stringprintf.h"
  18. #include "chromeos/crosapi/mojom/account_manager.mojom.h"
  19. #include "components/account_manager_core/account.h"
  20. #include "components/account_manager_core/account_addition_result.h"
  21. #include "components/account_manager_core/account_manager_util.h"
  22. #include "components/account_manager_core/chromeos/account_manager.h"
  23. #include "components/account_manager_core/chromeos/account_manager_facade_factory.h"
  24. #include "google_apis/gaia/google_service_auth_error.h"
  25. #include "google_apis/gaia/oauth2_access_token_consumer.h"
  26. #include "google_apis/gaia/oauth2_access_token_fetcher.h"
  27. #include "google_apis/gaia/oauth2_access_token_fetcher_immediate_error.h"
  28. #include "third_party/abseil-cpp/absl/types/optional.h"
  29. namespace account_manager {
  30. namespace {
  31. using RemoteMinVersions = crosapi::mojom::AccountManager::MethodMinVersions;
  32. // UMA histogram names.
  33. const char kAccountAdditionResultStatus[] =
  34. "AccountManager.AccountAdditionResultStatus";
  35. const char kGetAccountsMojoStatus[] =
  36. "AccountManager.FacadeGetAccountsMojoStatus";
  37. const char kMojoDisconnectionsAccountManagerRemote[] =
  38. "AccountManager.MojoDisconnections.AccountManagerRemote";
  39. const char kMojoDisconnectionsAccountManagerObserverReceiver[] =
  40. "AccountManager.MojoDisconnections.AccountManagerObserverReceiver";
  41. const char kMojoDisconnectionsAccountManagerAccessTokenFetcherRemote[] =
  42. "AccountManager.MojoDisconnections.AccessTokenFetcherRemote";
  43. void UnmarshalAccounts(
  44. base::OnceCallback<void(const std::vector<Account>&)> callback,
  45. std::vector<crosapi::mojom::AccountPtr> mojo_accounts) {
  46. std::vector<Account> accounts;
  47. for (const auto& mojo_account : mojo_accounts) {
  48. absl::optional<Account> maybe_account = FromMojoAccount(mojo_account);
  49. if (!maybe_account) {
  50. // Skip accounts we couldn't unmarshal. No logging, as it would produce
  51. // a lot of noise.
  52. continue;
  53. }
  54. accounts.emplace_back(std::move(maybe_account.value()));
  55. }
  56. std::move(callback).Run(std::move(accounts));
  57. }
  58. void UnmarshalPersistentError(
  59. base::OnceCallback<void(const GoogleServiceAuthError&)> callback,
  60. crosapi::mojom::GoogleServiceAuthErrorPtr mojo_error) {
  61. absl::optional<GoogleServiceAuthError> maybe_error =
  62. FromMojoGoogleServiceAuthError(mojo_error);
  63. if (!maybe_error) {
  64. // Couldn't unmarshal GoogleServiceAuthError, report the account as not
  65. // having an error. This is safe to do, as GetPersistentErrorForAccount is
  66. // best-effort (there's no way to know that the token was revoked on the
  67. // server).
  68. std::move(callback).Run(GoogleServiceAuthError::AuthErrorNone());
  69. return;
  70. }
  71. std::move(callback).Run(maybe_error.value());
  72. }
  73. // Returns whether an account should be available in ARC after it's added
  74. // in-session.
  75. bool GetIsAvailableInArcBySource(
  76. AccountManagerFacade::AccountAdditionSource source) {
  77. switch (source) {
  78. // Accounts added from Ash should be available in ARC.
  79. case AccountManagerFacade::AccountAdditionSource::kSettingsAddAccountButton:
  80. case AccountManagerFacade::AccountAdditionSource::
  81. kAccountManagerMigrationWelcomeScreen:
  82. case AccountManagerFacade::AccountAdditionSource::kArc:
  83. case AccountManagerFacade::AccountAdditionSource::kOnboarding:
  84. return true;
  85. // Accounts added from the browser should not be available in ARC.
  86. case AccountManagerFacade::AccountAdditionSource::kChromeProfileCreation:
  87. case AccountManagerFacade::AccountAdditionSource::kOgbAddAccount:
  88. case AccountManagerFacade::AccountAdditionSource::
  89. kAvatarBubbleTurnOnSyncAddAccount:
  90. case AccountManagerFacade::AccountAdditionSource::
  91. kChromeExtensionAddAccount:
  92. case AccountManagerFacade::AccountAdditionSource::
  93. kChromeSyncPromoAddAccount:
  94. case AccountManagerFacade::AccountAdditionSource::
  95. kChromeSettingsTurnOnSyncButton:
  96. return false;
  97. // These are reauthentication cases. ARC visibility shouldn't change for
  98. // reauthentication.
  99. case AccountManagerFacade::AccountAdditionSource::kContentAreaReauth:
  100. case AccountManagerFacade::AccountAdditionSource::
  101. kSettingsReauthAccountButton:
  102. case AccountManagerFacade::AccountAdditionSource::
  103. kAvatarBubbleReauthAccountButton:
  104. case AccountManagerFacade::AccountAdditionSource::kChromeExtensionReauth:
  105. case AccountManagerFacade::AccountAdditionSource::kChromeSyncPromoReauth:
  106. case AccountManagerFacade::AccountAdditionSource::
  107. kChromeSettingsReauthAccountButton:
  108. NOTREACHED();
  109. return false;
  110. // Unused enums that cannot be deleted.
  111. case AccountManagerFacade::AccountAdditionSource::kPrintPreviewDialogUnused:
  112. NOTREACHED();
  113. return false;
  114. }
  115. }
  116. // Error logs the Mojo connection stats when `event` occurs.
  117. void LogMojoConnectionStats(const std::string& event,
  118. int num_remote_disconnections,
  119. int num_receiver_disconnections) {
  120. LOG(ERROR) << base::StringPrintf(
  121. "%s. Number of remote disconnections: %d, "
  122. "number of receiver disconnections: %d",
  123. event.c_str(), num_remote_disconnections, num_receiver_disconnections);
  124. }
  125. } // namespace
  126. // Fetches access tokens over the Mojo remote to `AccountManager`.
  127. class AccountManagerFacadeImpl::AccessTokenFetcher
  128. : public OAuth2AccessTokenFetcher {
  129. public:
  130. AccessTokenFetcher(AccountManagerFacadeImpl* account_manager_facade_impl,
  131. const account_manager::AccountKey& account_key,
  132. OAuth2AccessTokenConsumer* consumer)
  133. : OAuth2AccessTokenFetcher(consumer),
  134. account_manager_facade_impl_(account_manager_facade_impl),
  135. account_key_(account_key),
  136. oauth_consumer_name_(consumer->GetConsumerName()) {}
  137. AccessTokenFetcher(const AccessTokenFetcher&) = delete;
  138. AccessTokenFetcher& operator=(const AccessTokenFetcher&) = delete;
  139. ~AccessTokenFetcher() override {
  140. base::UmaHistogramCounts100(
  141. kMojoDisconnectionsAccountManagerAccessTokenFetcherRemote,
  142. num_remote_disconnections_);
  143. }
  144. // Returns a closure, which marks `this` instance as ready for use. This
  145. // happens when `AccountManagerFacadeImpl`'s initialization sequence is
  146. // complete.
  147. base::OnceClosure UnblockTokenRequest() {
  148. return base::BindOnce(&AccessTokenFetcher::UnblockTokenRequestInternal,
  149. weak_factory_.GetWeakPtr());
  150. }
  151. // Returns a closure which handles Mojo connection errors tied to Account
  152. // Manager remote.
  153. base::OnceClosure AccountManagerRemoteDisconnectionClosure() {
  154. return base::BindOnce(
  155. &AccessTokenFetcher::OnAccountManagerRemoteDisconnection,
  156. weak_factory_.GetWeakPtr());
  157. }
  158. // OAuth2AccessTokenFetcher override:
  159. // Note: This implementation ignores `client_id` and `client_secret` because
  160. // AccountManager's Mojo API does not support overriding OAuth client id and
  161. // secret.
  162. void Start(const std::string& client_id,
  163. const std::string& client_secret,
  164. const std::vector<std::string>& scopes) override {
  165. DCHECK(!is_request_pending_);
  166. is_request_pending_ = true;
  167. scopes_ = scopes;
  168. if (!are_token_requests_allowed_) {
  169. return;
  170. }
  171. StartInternal();
  172. }
  173. // OAuth2AccessTokenFetcher override:
  174. void CancelRequest() override {
  175. access_token_fetcher_.reset();
  176. is_request_pending_ = false;
  177. }
  178. private:
  179. void UnblockTokenRequestInternal() {
  180. are_token_requests_allowed_ = true;
  181. if (is_request_pending_) {
  182. StartInternal();
  183. }
  184. }
  185. void StartInternal() {
  186. DCHECK(are_token_requests_allowed_);
  187. bool is_remote_connected =
  188. account_manager_facade_impl_->CreateAccessTokenFetcher(
  189. account_manager::ToMojoAccountKey(account_key_),
  190. oauth_consumer_name_,
  191. base::BindOnce(&AccessTokenFetcher::FetchAccessToken,
  192. weak_factory_.GetWeakPtr()));
  193. if (!is_remote_connected) {
  194. OnAccountManagerRemoteDisconnection();
  195. }
  196. }
  197. void FetchAccessToken(
  198. mojo::PendingRemote<crosapi::mojom::AccessTokenFetcher> pending_remote) {
  199. access_token_fetcher_.Bind(std::move(pending_remote));
  200. access_token_fetcher_.set_disconnect_handler(base::BindOnce(
  201. &AccessTokenFetcher::OnAccessTokenFetcherRemoteDisconnection,
  202. weak_factory_.GetWeakPtr()));
  203. access_token_fetcher_->Start(
  204. scopes_, base::BindOnce(&AccessTokenFetcher::OnAccessTokenFetchComplete,
  205. weak_factory_.GetWeakPtr()));
  206. }
  207. void OnAccessTokenFetchComplete(crosapi::mojom::AccessTokenResultPtr result) {
  208. DCHECK(is_request_pending_);
  209. is_request_pending_ = false;
  210. if (result->is_error()) {
  211. absl::optional<GoogleServiceAuthError> maybe_error =
  212. account_manager::FromMojoGoogleServiceAuthError(result->get_error());
  213. if (!maybe_error.has_value()) {
  214. LOG(ERROR) << "Unable to parse error result of access token fetch: "
  215. << result->get_error()->state;
  216. FireOnGetTokenFailure(GoogleServiceAuthError(
  217. GoogleServiceAuthError::State::UNEXPECTED_SERVICE_RESPONSE));
  218. } else {
  219. FireOnGetTokenFailure(maybe_error.value());
  220. }
  221. return;
  222. }
  223. FireOnGetTokenSuccess(
  224. OAuth2AccessTokenConsumer::TokenResponse::Builder()
  225. .WithAccessToken(result->get_access_token_info()->access_token)
  226. .WithExpirationTime(
  227. result->get_access_token_info()->expiration_time)
  228. .WithIdToken(result->get_access_token_info()->id_token)
  229. .build());
  230. }
  231. void OnAccountManagerRemoteDisconnection() {
  232. FailPendingRequestWithServiceError("Mojo pipe disconnected");
  233. }
  234. void OnAccessTokenFetcherRemoteDisconnection() {
  235. num_remote_disconnections_++;
  236. LOG(ERROR) << "Access token fetcher remote disconnected";
  237. FailPendingRequestWithServiceError("Access token Mojo pipe disconnected");
  238. }
  239. void FailPendingRequestWithServiceError(const std::string& message) {
  240. if (!is_request_pending_)
  241. return;
  242. CancelRequest();
  243. FireOnGetTokenFailure(GoogleServiceAuthError::FromServiceError(message));
  244. }
  245. const raw_ptr<AccountManagerFacadeImpl> account_manager_facade_impl_;
  246. const account_manager::AccountKey account_key_;
  247. const std::string oauth_consumer_name_;
  248. bool are_token_requests_allowed_ = false;
  249. bool is_request_pending_ = false;
  250. // Number of Mojo pipe disconnections seen by `access_token_fetcher_`.
  251. int num_remote_disconnections_ = 0;
  252. std::vector<std::string> scopes_;
  253. mojo::Remote<crosapi::mojom::AccessTokenFetcher> access_token_fetcher_;
  254. base::WeakPtrFactory<AccessTokenFetcher> weak_factory_{this};
  255. };
  256. AccountManagerFacadeImpl::AccountManagerFacadeImpl(
  257. mojo::Remote<crosapi::mojom::AccountManager> account_manager_remote,
  258. uint32_t remote_version,
  259. AccountManager* account_manager_for_tests,
  260. base::OnceClosure init_finished)
  261. : remote_version_(remote_version),
  262. account_manager_remote_(std::move(account_manager_remote)),
  263. account_manager_for_tests_(account_manager_for_tests) {
  264. DCHECK(init_finished);
  265. initialization_callbacks_.emplace_back(std::move(init_finished));
  266. if (!account_manager_remote_ ||
  267. remote_version_ < RemoteMinVersions::kGetAccountsMinVersion) {
  268. LOG(WARNING) << "Found remote at: " << remote_version_
  269. << ", expected: " << RemoteMinVersions::kGetAccountsMinVersion
  270. << ". Account consistency will be disabled";
  271. FinishInitSequenceIfNotAlreadyFinished();
  272. return;
  273. }
  274. account_manager_remote_.set_disconnect_handler(base::BindOnce(
  275. &AccountManagerFacadeImpl::OnAccountManagerRemoteDisconnected,
  276. weak_factory_.GetWeakPtr()));
  277. account_manager_remote_->AddObserver(
  278. base::BindOnce(&AccountManagerFacadeImpl::OnReceiverReceived,
  279. weak_factory_.GetWeakPtr()));
  280. }
  281. AccountManagerFacadeImpl::~AccountManagerFacadeImpl() {
  282. base::UmaHistogramCounts100(kMojoDisconnectionsAccountManagerRemote,
  283. num_remote_disconnections_);
  284. base::UmaHistogramCounts100(kMojoDisconnectionsAccountManagerObserverReceiver,
  285. num_receiver_disconnections_);
  286. }
  287. void AccountManagerFacadeImpl::AddObserver(Observer* observer) {
  288. observer_list_.AddObserver(observer);
  289. }
  290. void AccountManagerFacadeImpl::RemoveObserver(Observer* observer) {
  291. observer_list_.RemoveObserver(observer);
  292. }
  293. void AccountManagerFacadeImpl::GetAccounts(
  294. base::OnceCallback<void(const std::vector<Account>&)> callback) {
  295. // Record the status of the mojo connection, to get more information about
  296. // https://crbug.com/1287297
  297. FacadeMojoStatus mojo_status = FacadeMojoStatus::kOk;
  298. if (!account_manager_remote_)
  299. mojo_status = FacadeMojoStatus::kNoRemote;
  300. else if (remote_version_ < RemoteMinVersions::kGetAccountsMinVersion)
  301. mojo_status = FacadeMojoStatus::kVersionMismatch;
  302. else if (!is_initialized_)
  303. mojo_status = FacadeMojoStatus::kUninitialized;
  304. base::UmaHistogramEnumeration(kGetAccountsMojoStatus, mojo_status);
  305. if (!account_manager_remote_ ||
  306. remote_version_ < RemoteMinVersions::kGetAccountsMinVersion) {
  307. // Remote side is disconnected or doesn't support GetAccounts. Do not return
  308. // an empty list as that may cause Lacros to delete user profiles.
  309. // TODO(https://crbug.com/1287297): Try to reconnect, or return an error.
  310. return;
  311. }
  312. RunAfterInitializationSequence(
  313. base::BindOnce(&AccountManagerFacadeImpl::GetAccountsInternal,
  314. weak_factory_.GetWeakPtr(), std::move(callback)));
  315. }
  316. void AccountManagerFacadeImpl::GetPersistentErrorForAccount(
  317. const AccountKey& account,
  318. base::OnceCallback<void(const GoogleServiceAuthError&)> callback) {
  319. if (!account_manager_remote_ ||
  320. remote_version_ <
  321. RemoteMinVersions::kGetPersistentErrorForAccountMinVersion) {
  322. // Remote side doesn't support GetPersistentErrorForAccount.
  323. std::move(callback).Run(GoogleServiceAuthError::AuthErrorNone());
  324. return;
  325. }
  326. RunAfterInitializationSequence(
  327. base::BindOnce(&AccountManagerFacadeImpl::GetPersistentErrorInternal,
  328. weak_factory_.GetWeakPtr(), account, std::move(callback)));
  329. }
  330. void AccountManagerFacadeImpl::ShowAddAccountDialog(
  331. AccountAdditionSource source) {
  332. ShowAddAccountDialog(source, base::DoNothing());
  333. }
  334. void AccountManagerFacadeImpl::ShowAddAccountDialog(
  335. AccountAdditionSource source,
  336. base::OnceCallback<
  337. void(const account_manager::AccountAdditionResult& result)> callback) {
  338. if (!account_manager_remote_ ||
  339. remote_version_ < RemoteMinVersions::kShowAddAccountDialogMinVersion) {
  340. LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: "
  341. << RemoteMinVersions::kShowAddAccountDialogMinVersion
  342. << " for ShowAddAccountDialog.";
  343. FinishAddAccount(std::move(callback),
  344. account_manager::AccountAdditionResult::FromStatus(
  345. account_manager::AccountAdditionResult::Status::
  346. kUnexpectedResponse));
  347. return;
  348. }
  349. base::UmaHistogramEnumeration(kAccountAdditionSource, source);
  350. crosapi::mojom::AccountAdditionOptionsPtr options =
  351. crosapi::mojom::AccountAdditionOptions::New();
  352. options->is_available_in_arc = GetIsAvailableInArcBySource(source);
  353. options->show_arc_availability_picker =
  354. (source == AccountManagerFacade::AccountAdditionSource::kArc);
  355. account_manager_remote_->ShowAddAccountDialog(
  356. std::move(options),
  357. base::BindOnce(&AccountManagerFacadeImpl::OnShowAddAccountDialogFinished,
  358. weak_factory_.GetWeakPtr(), std::move(callback)));
  359. }
  360. void AccountManagerFacadeImpl::ShowReauthAccountDialog(
  361. AccountAdditionSource source,
  362. const std::string& email,
  363. base::OnceClosure callback) {
  364. if (!account_manager_remote_ ||
  365. remote_version_ < RemoteMinVersions::kShowReauthAccountDialogMinVersion) {
  366. LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: "
  367. << RemoteMinVersions::kShowReauthAccountDialogMinVersion
  368. << " for ShowReauthAccountDialog.";
  369. if (callback)
  370. std::move(callback).Run();
  371. return;
  372. }
  373. base::UmaHistogramEnumeration(kAccountAdditionSource, source);
  374. account_manager_remote_->ShowReauthAccountDialog(email, std::move(callback));
  375. }
  376. void AccountManagerFacadeImpl::ShowManageAccountsSettings() {
  377. if (!account_manager_remote_ ||
  378. remote_version_ <
  379. RemoteMinVersions::kShowManageAccountsSettingsMinVersion) {
  380. LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: "
  381. << RemoteMinVersions::kShowManageAccountsSettingsMinVersion
  382. << " for ShowManageAccountsSettings.";
  383. return;
  384. }
  385. account_manager_remote_->ShowManageAccountsSettings();
  386. }
  387. std::unique_ptr<OAuth2AccessTokenFetcher>
  388. AccountManagerFacadeImpl::CreateAccessTokenFetcher(
  389. const AccountKey& account,
  390. OAuth2AccessTokenConsumer* consumer) {
  391. if (!account_manager_remote_ ||
  392. remote_version_ <
  393. RemoteMinVersions::kCreateAccessTokenFetcherMinVersion) {
  394. VLOG(1) << "Found remote at: " << remote_version_ << ", expected: "
  395. << RemoteMinVersions::kCreateAccessTokenFetcherMinVersion
  396. << " for CreateAccessTokenFetcher";
  397. return std::make_unique<OAuth2AccessTokenFetcherImmediateError>(
  398. consumer,
  399. GoogleServiceAuthError::FromServiceError("Mojo pipe disconnected"));
  400. }
  401. auto access_token_fetcher = std::make_unique<AccessTokenFetcher>(
  402. /*account_manager_facade_impl=*/this, account, consumer);
  403. RunAfterInitializationSequence(access_token_fetcher->UnblockTokenRequest());
  404. RunOnAccountManagerRemoteDisconnection(
  405. access_token_fetcher->AccountManagerRemoteDisconnectionClosure());
  406. return std::move(access_token_fetcher);
  407. }
  408. void AccountManagerFacadeImpl::ReportAuthError(
  409. const account_manager::AccountKey& account,
  410. const GoogleServiceAuthError& error) {
  411. if (!account_manager_remote_ ||
  412. remote_version_ < RemoteMinVersions::kReportAuthErrorMinVersion) {
  413. LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: "
  414. << RemoteMinVersions::kReportAuthErrorMinVersion
  415. << " for ReportAuthError.";
  416. return;
  417. }
  418. account_manager_remote_->ReportAuthError(ToMojoAccountKey(account),
  419. ToMojoGoogleServiceAuthError(error));
  420. }
  421. void AccountManagerFacadeImpl::UpsertAccountForTesting(
  422. const Account& account,
  423. const std::string& token_value) {
  424. account_manager_for_tests_->UpsertAccount(account.key, account.raw_email,
  425. token_value);
  426. }
  427. void AccountManagerFacadeImpl::RemoveAccountForTesting(
  428. const AccountKey& account) {
  429. account_manager_for_tests_->RemoveAccount(account);
  430. }
  431. // static
  432. std::string AccountManagerFacadeImpl::
  433. GetAccountAdditionResultStatusHistogramNameForTesting() {
  434. return kAccountAdditionResultStatus;
  435. }
  436. // static
  437. std::string
  438. AccountManagerFacadeImpl::GetAccountsMojoStatusHistogramNameForTesting() {
  439. return kGetAccountsMojoStatus;
  440. }
  441. void AccountManagerFacadeImpl::OnReceiverReceived(
  442. mojo::PendingReceiver<AccountManagerObserver> receiver) {
  443. receiver_ =
  444. std::make_unique<mojo::Receiver<crosapi::mojom::AccountManagerObserver>>(
  445. this, std::move(receiver));
  446. // At this point (`receiver_` exists), we are subscribed to Account Manager.
  447. receiver_->set_disconnect_handler(base::BindOnce(
  448. &AccountManagerFacadeImpl::OnAccountManagerObserverReceiverDisconnected,
  449. weak_factory_.GetWeakPtr()));
  450. FinishInitSequenceIfNotAlreadyFinished();
  451. }
  452. void AccountManagerFacadeImpl::OnShowAddAccountDialogFinished(
  453. base::OnceCallback<
  454. void(const account_manager::AccountAdditionResult& result)> callback,
  455. crosapi::mojom::AccountAdditionResultPtr mojo_result) {
  456. absl::optional<account_manager::AccountAdditionResult> result =
  457. account_manager::FromMojoAccountAdditionResult(mojo_result);
  458. if (!result.has_value()) {
  459. FinishAddAccount(std::move(callback),
  460. account_manager::AccountAdditionResult::FromStatus(
  461. account_manager::AccountAdditionResult::Status::
  462. kUnexpectedResponse));
  463. return;
  464. }
  465. FinishAddAccount(std::move(callback), result.value());
  466. }
  467. void AccountManagerFacadeImpl::FinishAddAccount(
  468. base::OnceCallback<
  469. void(const account_manager::AccountAdditionResult& result)> callback,
  470. const account_manager::AccountAdditionResult& result) {
  471. base::UmaHistogramEnumeration(kAccountAdditionResultStatus, result.status());
  472. std::move(callback).Run(result);
  473. }
  474. void AccountManagerFacadeImpl::OnTokenUpserted(
  475. crosapi::mojom::AccountPtr account) {
  476. absl::optional<Account> maybe_account = FromMojoAccount(account);
  477. if (!maybe_account) {
  478. LOG(WARNING) << "Can't unmarshal account of type: "
  479. << account->key->account_type;
  480. return;
  481. }
  482. for (auto& observer : observer_list_) {
  483. observer.OnAccountUpserted(maybe_account.value());
  484. }
  485. }
  486. void AccountManagerFacadeImpl::OnAccountRemoved(
  487. crosapi::mojom::AccountPtr account) {
  488. absl::optional<Account> maybe_account = FromMojoAccount(account);
  489. if (!maybe_account) {
  490. LOG(WARNING) << "Can't unmarshal account of type: "
  491. << account->key->account_type;
  492. return;
  493. }
  494. for (auto& observer : observer_list_) {
  495. observer.OnAccountRemoved(maybe_account.value());
  496. }
  497. }
  498. void AccountManagerFacadeImpl::OnAuthErrorChanged(
  499. crosapi::mojom::AccountKeyPtr account,
  500. crosapi::mojom::GoogleServiceAuthErrorPtr error) {
  501. NOTIMPLEMENTED();
  502. }
  503. void AccountManagerFacadeImpl::GetAccountsInternal(
  504. base::OnceCallback<void(const std::vector<Account>&)> callback) {
  505. account_manager_remote_->GetAccounts(
  506. base::BindOnce(&UnmarshalAccounts, std::move(callback)));
  507. }
  508. void AccountManagerFacadeImpl::GetPersistentErrorInternal(
  509. const AccountKey& account,
  510. base::OnceCallback<void(const GoogleServiceAuthError&)> callback) {
  511. account_manager_remote_->GetPersistentErrorForAccount(
  512. ToMojoAccountKey(account),
  513. base::BindOnce(&UnmarshalPersistentError, std::move(callback)));
  514. }
  515. bool AccountManagerFacadeImpl::CreateAccessTokenFetcher(
  516. crosapi::mojom::AccountKeyPtr account_key,
  517. const std::string& oauth_consumer_name,
  518. crosapi::mojom::AccountManager::CreateAccessTokenFetcherCallback callback) {
  519. if (!account_manager_remote_) {
  520. return false;
  521. }
  522. account_manager_remote_->CreateAccessTokenFetcher(
  523. std::move(account_key), oauth_consumer_name, std::move(callback));
  524. return true;
  525. }
  526. void AccountManagerFacadeImpl::FinishInitSequenceIfNotAlreadyFinished() {
  527. if (is_initialized_) {
  528. return;
  529. }
  530. is_initialized_ = true;
  531. for (auto& cb : initialization_callbacks_) {
  532. std::move(cb).Run();
  533. }
  534. initialization_callbacks_.clear();
  535. }
  536. void AccountManagerFacadeImpl::RunAfterInitializationSequence(
  537. base::OnceClosure closure) {
  538. if (!is_initialized_) {
  539. initialization_callbacks_.emplace_back(std::move(closure));
  540. } else {
  541. std::move(closure).Run();
  542. }
  543. }
  544. void AccountManagerFacadeImpl::RunOnAccountManagerRemoteDisconnection(
  545. base::OnceClosure closure) {
  546. if (!account_manager_remote_) {
  547. std::move(closure).Run();
  548. return;
  549. }
  550. account_manager_remote_disconnection_handlers_.emplace_back(
  551. std::move(closure));
  552. }
  553. void AccountManagerFacadeImpl::OnAccountManagerRemoteDisconnected() {
  554. num_remote_disconnections_++;
  555. LogMojoConnectionStats("Account Manager disconnected",
  556. num_remote_disconnections_,
  557. num_receiver_disconnections_);
  558. for (auto& cb : account_manager_remote_disconnection_handlers_) {
  559. std::move(cb).Run();
  560. }
  561. account_manager_remote_disconnection_handlers_.clear();
  562. account_manager_remote_.reset();
  563. }
  564. void AccountManagerFacadeImpl::OnAccountManagerObserverReceiverDisconnected() {
  565. num_receiver_disconnections_++;
  566. LogMojoConnectionStats("Account Manager Observer disconnected",
  567. num_remote_disconnections_,
  568. num_receiver_disconnections_);
  569. }
  570. bool AccountManagerFacadeImpl::IsInitialized() {
  571. return is_initialized_;
  572. }
  573. void AccountManagerFacadeImpl::FlushMojoForTesting() {
  574. if (!account_manager_remote_) {
  575. return;
  576. }
  577. account_manager_remote_.FlushForTesting();
  578. }
  579. } // namespace account_manager