chromium/chrome/browser/password_manager/android/android_backend_with_double_deletion.cc

// Copyright 2024 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/password_manager/android/android_backend_with_double_deletion.h"

#include <functional>
#include <memory>
#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "components/sync/model/proxy_data_type_controller_delegate.h"
#include "components/sync/service/sync_service.h"

namespace {

using password_manager::LoginsOrErrorReply;
using password_manager::PasswordChangesOrErrorReply;
using password_manager::PasswordForm;
using password_manager::PasswordFormDigest;

}  // namespace

AndroidBackendWithDoubleDeletion::AndroidBackendWithDoubleDeletion(
    std::unique_ptr<PasswordStoreBackend> built_in_backend,
    std::unique_ptr<PasswordStoreBackend> android_backend)
    : built_in_backend_(std::move(built_in_backend)),
      android_backend_(std::move(android_backend)) {}

AndroidBackendWithDoubleDeletion::~AndroidBackendWithDoubleDeletion() = default;

void AndroidBackendWithDoubleDeletion::InitBackend(
    password_manager::AffiliatedMatchHelper* affiliated_match_helper,
    RemoteChangesReceived remote_form_changes_received,
    base::RepeatingClosure sync_enabled_or_disabled_cb,
    base::OnceCallback<void(bool)> completion) {
  // `sync_enabled_or_disabled_cb` can be invoked by `built_in_backend_` only if
  // M4 feature flag is disabled. After M4 is enabled LoginDatabase has no
  // connection to the sync engine, preventing any internal changes on sync
  // events.
  built_in_backend_->InitBackend(affiliated_match_helper, base::DoNothing(),
                                 sync_enabled_or_disabled_cb,
                                 base::DoNothing());

  // `sync_enabled_or_disabled_cb` can be invoked by `android_backend_` only if
  // M4 feature flag is enabled and the `android_backend_` is an account
  // backend. The callback is invoked when sync status changes are detected.
  android_backend_->InitBackend(
      affiliated_match_helper, std::move(remote_form_changes_received),
      std::move(sync_enabled_or_disabled_cb), std::move(completion));
}

void AndroidBackendWithDoubleDeletion::Shutdown(
    base::OnceClosure shutdown_completed) {
  weak_ptr_factory_.InvalidateWeakPtrs();
  auto shutdown_closure =
      base::BarrierClosure(2, std::move(shutdown_completed));
  built_in_backend_->Shutdown(
      base::BindOnce(shutdown_closure)
          .Then(base::OnceClosure(
              base::DoNothingWithBoundArgs(std::move(built_in_backend_)))));
  android_backend_->Shutdown(
      base::BindOnce(shutdown_closure)
          .Then(base::OnceClosure(
              base::DoNothingWithBoundArgs(std::move(android_backend_)))));
}

bool AndroidBackendWithDoubleDeletion::IsAbleToSavePasswords() {
  return android_backend_->IsAbleToSavePasswords();
}
void AndroidBackendWithDoubleDeletion::GetAllLoginsAsync(
    LoginsOrErrorReply callback) {
  android_backend_->GetAllLoginsAsync(std::move(callback));
}

void AndroidBackendWithDoubleDeletion::
    GetAllLoginsWithAffiliationAndBrandingAsync(LoginsOrErrorReply callback) {
  android_backend_->GetAllLoginsWithAffiliationAndBrandingAsync(
      std::move(callback));
}

void AndroidBackendWithDoubleDeletion::GetAutofillableLoginsAsync(
    LoginsOrErrorReply callback) {
  android_backend_->GetAutofillableLoginsAsync(std::move(callback));
}

void AndroidBackendWithDoubleDeletion::GetAllLoginsForAccountAsync(
    std::string account,
    LoginsOrErrorReply callback) {
  NOTREACHED();
}

void AndroidBackendWithDoubleDeletion::FillMatchingLoginsAsync(
    LoginsOrErrorReply callback,
    bool include_psl,
    const std::vector<PasswordFormDigest>& forms) {
  android_backend_->FillMatchingLoginsAsync(std::move(callback), include_psl,
                                            forms);
}

void AndroidBackendWithDoubleDeletion::GetGroupedMatchingLoginsAsync(
    const PasswordFormDigest& form_digest,
    LoginsOrErrorReply callback) {
  android_backend_->GetGroupedMatchingLoginsAsync(form_digest,
                                                  std::move(callback));
}

void AndroidBackendWithDoubleDeletion::AddLoginAsync(
    const PasswordForm& form,
    PasswordChangesOrErrorReply callback) {
  android_backend_->AddLoginAsync(form, std::move(callback));
}

void AndroidBackendWithDoubleDeletion::UpdateLoginAsync(
    const PasswordForm& form,
    PasswordChangesOrErrorReply callback) {
  android_backend_->UpdateLoginAsync(form, std::move(callback));
}

void AndroidBackendWithDoubleDeletion::RemoveLoginAsync(
    const base::Location& location,
    const PasswordForm& form,
    PasswordChangesOrErrorReply callback) {
  android_backend_->RemoveLoginAsync(location, form, std::move(callback));
  built_in_backend_->RemoveLoginAsync(location, form, base::DoNothing());
}

void AndroidBackendWithDoubleDeletion::RemoveLoginsByURLAndTimeAsync(
    const base::Location& location,
    const base::RepeatingCallback<bool(const GURL&)>& url_filter,
    base::Time delete_begin,
    base::Time delete_end,
    base::OnceCallback<void(bool)> sync_completion,
    PasswordChangesOrErrorReply callback) {
  // The `sync_completion` callback is only relevant for account passwords
  // which don't exist on Android, so it is not passed in and can be ignored
  // later.
  CHECK(!sync_completion);
  android_backend_->RemoveLoginsByURLAndTimeAsync(
      location, url_filter, delete_begin, delete_end, base::NullCallback(),
      std::move(callback));
  built_in_backend_->RemoveLoginsByURLAndTimeAsync(
      location, url_filter, delete_begin, delete_end, base::NullCallback(),
      base::DoNothing());
}

void AndroidBackendWithDoubleDeletion::RemoveLoginsCreatedBetweenAsync(
    const base::Location& location,
    base::Time delete_begin,
    base::Time delete_end,
    PasswordChangesOrErrorReply callback) {
  android_backend_->RemoveLoginsCreatedBetweenAsync(
      location, delete_begin, delete_end, std::move(callback));
  built_in_backend_->RemoveLoginsCreatedBetweenAsync(
      location, delete_begin, delete_end, base::DoNothing());
}

void AndroidBackendWithDoubleDeletion::DisableAutoSignInForOriginsAsync(
    const base::RepeatingCallback<bool(const GURL&)>& origin_filter,
    base::OnceClosure completion) {
  android_backend_->DisableAutoSignInForOriginsAsync(origin_filter,
                                                     std::move(completion));
}

password_manager::SmartBubbleStatsStore*
AndroidBackendWithDoubleDeletion::GetSmartBubbleStatsStore() {
  return android_backend_->GetSmartBubbleStatsStore();
}

std::unique_ptr<syncer::DataTypeControllerDelegate>
AndroidBackendWithDoubleDeletion::CreateSyncControllerDelegate() {
  return built_in_backend_->CreateSyncControllerDelegate();
}

void AndroidBackendWithDoubleDeletion::OnSyncServiceInitialized(
    syncer::SyncService* sync_service) {
  android_backend_->OnSyncServiceInitialized(sync_service);
}

void AndroidBackendWithDoubleDeletion::RecordAddLoginAsyncCalledFromTheStore() {
  android_backend_->RecordAddLoginAsyncCalledFromTheStore();
}

void AndroidBackendWithDoubleDeletion::
    RecordUpdateLoginAsyncCalledFromTheStore() {
  android_backend_->RecordUpdateLoginAsyncCalledFromTheStore();
}

base::WeakPtr<password_manager::PasswordStoreBackend>
AndroidBackendWithDoubleDeletion::AsWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}