chromium/chrome/browser/password_manager/android/account_storage_notice/account_storage_notice.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/account_storage_notice/account_storage_notice.h"

#include <utility>

#include "base/android/jni_android.h"
#include "base/check.h"
#include "base/memory/ptr_util.h"
#include "components/password_manager/core/browser/password_sync_util.h"
#include "components/password_manager/core/browser/split_stores_and_local_upm.h"
#include "components/prefs/pref_service.h"
#include "components/sync/service/sync_service.h"
#include "ui/android/window_android.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "chrome/browser/password_manager/android/account_storage_notice/jni/AccountStorageNoticeCoordinator_jni.h"

using base::android::AttachCurrentThread;

// static
std::unique_ptr<AccountStorageNotice> AccountStorageNotice::MaybeShow(
    syncer::SyncService* sync_service,
    PrefService* pref_service,
    ui::WindowAndroid* window_android,
    base::OnceClosure done_cb) {
  bool can_show = Java_AccountStorageNoticeCoordinator_canShow(
      AttachCurrentThread(),
      sync_service ? sync_service->HasSyncConsent() : false,
      password_manager::sync_util::HasChosenToSyncPasswords(sync_service),
      password_manager::IsGmsCoreUpdateRequired(pref_service, sync_service),
      pref_service->GetJavaObject(),
      window_android ? window_android->GetJavaObject() : nullptr);
  if (can_show) {
    base::android::ScopedJavaLocalRef<jobject> java_coordinator =
        Java_AccountStorageNoticeCoordinator_createAndShow(
            AttachCurrentThread(), window_android->GetJavaObject(),
            pref_service->GetJavaObject());
    return base::WrapUnique(
        new AccountStorageNotice(java_coordinator, std::move(done_cb)));
  }
  // Creation failed, reply immediately.
  std::move(done_cb).Run();
  return nullptr;
}

AccountStorageNotice::AccountStorageNotice(
    base::android::ScopedJavaLocalRef<jobject> java_coordinator,
    base::OnceClosure done_cb)
    : java_coordinator_(java_coordinator), done_cb_(std::move(done_cb)) {
  CHECK(java_coordinator_);
  CHECK(done_cb_);
  Java_AccountStorageNoticeCoordinator_setObserver(
      AttachCurrentThread(), java_coordinator_,
      reinterpret_cast<intptr_t>(this));
}

AccountStorageNotice::~AccountStorageNotice() {
  // Remove the observer *before* calling hideImmediatelyIfShowing(), because we
  // don't want to trigger OnClosed() and `done_cb` if the sheet was still
  // showing.
  Java_AccountStorageNoticeCoordinator_setObserver(AttachCurrentThread(),
                                                   java_coordinator_, 0);
  Java_AccountStorageNoticeCoordinator_hideImmediatelyIfShowing(
      AttachCurrentThread(), java_coordinator_);
}

void AccountStorageNotice::OnClosed(JNIEnv* env) {
  std::move(done_cb_).Run();
  // `done_cb_` might have deleted the object above, do nothing else.
}