2020-07-04 04:51:17 +02:00
|
|
|
// Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "libcef/browser/chrome/chrome_browser_context.h"
|
|
|
|
|
2021-04-15 01:28:22 +02:00
|
|
|
#include "libcef/browser/thread_util.h"
|
2020-09-25 03:40:47 +02:00
|
|
|
|
2021-08-04 21:19:00 +02:00
|
|
|
#include "base/threading/thread_restrictions.h"
|
2021-04-07 00:09:45 +02:00
|
|
|
#include "chrome/browser/browser_process.h"
|
2022-03-23 01:42:03 +01:00
|
|
|
#include "chrome/browser/prefs/session_startup_pref.h"
|
2022-01-25 21:26:51 +01:00
|
|
|
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
|
|
|
|
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
|
2021-04-09 20:34:45 +02:00
|
|
|
#include "chrome/browser/profiles/off_the_record_profile_impl.h"
|
2022-03-23 01:42:03 +01:00
|
|
|
#include "chrome/common/pref_names.h"
|
2020-07-04 04:51:17 +02:00
|
|
|
|
2023-01-03 00:34:43 +01:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// Match the default logic from ProfileManager::GetPrimaryUserProfile which was
|
|
|
|
// restricted in https://crbug.com/1264436.
|
|
|
|
Profile* GetPrimaryUserProfile() {
|
|
|
|
ProfileManager* profile_manager = g_browser_process->profile_manager();
|
|
|
|
|
|
|
|
// From ProfileManager::GetActiveUserOrOffTheRecordProfile.
|
|
|
|
base::FilePath default_profile_dir = profile_manager->user_data_dir().Append(
|
|
|
|
profile_manager->GetInitialProfileDir());
|
|
|
|
return profile_manager->GetProfile(default_profile_dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2020-07-04 04:51:17 +02:00
|
|
|
ChromeBrowserContext::ChromeBrowserContext(
|
|
|
|
const CefRequestContextSettings& settings)
|
2021-04-07 00:09:45 +02:00
|
|
|
: CefBrowserContext(settings), weak_ptr_factory_(this) {}
|
2020-07-04 04:51:17 +02:00
|
|
|
|
|
|
|
ChromeBrowserContext::~ChromeBrowserContext() = default;
|
|
|
|
|
|
|
|
content::BrowserContext* ChromeBrowserContext::AsBrowserContext() {
|
2021-07-23 21:55:22 +02:00
|
|
|
CHECK(!destroyed_);
|
2020-07-04 04:51:17 +02:00
|
|
|
return profile_;
|
|
|
|
}
|
|
|
|
|
|
|
|
Profile* ChromeBrowserContext::AsProfile() {
|
2021-07-23 21:55:22 +02:00
|
|
|
CHECK(!destroyed_);
|
2020-07-04 04:51:17 +02:00
|
|
|
return profile_;
|
|
|
|
}
|
|
|
|
|
2021-04-15 01:28:22 +02:00
|
|
|
bool ChromeBrowserContext::IsInitialized() const {
|
|
|
|
CEF_REQUIRE_UIT();
|
2021-07-23 21:55:22 +02:00
|
|
|
CHECK(!destroyed_);
|
2021-04-15 01:28:22 +02:00
|
|
|
return !!profile_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChromeBrowserContext::StoreOrTriggerInitCallback(
|
|
|
|
base::OnceClosure callback) {
|
|
|
|
CEF_REQUIRE_UIT();
|
|
|
|
if (IsInitialized()) {
|
|
|
|
std::move(callback).Run();
|
|
|
|
} else {
|
|
|
|
init_callbacks_.emplace_back(std::move(callback));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) {
|
2021-04-15 01:28:22 +02:00
|
|
|
init_callbacks_.emplace_back(std::move(initialized_cb));
|
2021-04-07 00:09:45 +02:00
|
|
|
|
2020-07-04 04:51:17 +02:00
|
|
|
CefBrowserContext::Initialize();
|
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
if (!cache_path_.empty()) {
|
|
|
|
auto* profile_manager = g_browser_process->profile_manager();
|
|
|
|
const auto& user_data_dir = profile_manager->user_data_dir();
|
|
|
|
|
|
|
|
if (cache_path_ == user_data_dir) {
|
|
|
|
// Use the default disk-based profile.
|
2023-01-03 00:34:43 +01:00
|
|
|
auto profile = GetPrimaryUserProfile();
|
2022-09-26 21:30:45 +02:00
|
|
|
ProfileCreated(Profile::CreateStatus::CREATE_STATUS_INITIALIZED, profile);
|
2021-04-07 00:09:45 +02:00
|
|
|
return;
|
|
|
|
} else if (cache_path_.DirName() == user_data_dir) {
|
|
|
|
// Create or load a specific disk-based profile. May continue
|
|
|
|
// synchronously or asynchronously.
|
|
|
|
profile_manager->CreateProfileAsync(
|
2021-06-04 03:34:56 +02:00
|
|
|
cache_path_,
|
2022-09-26 21:30:45 +02:00
|
|
|
base::BindOnce(&ChromeBrowserContext::ProfileCreated,
|
|
|
|
weak_ptr_factory_.GetWeakPtr(),
|
|
|
|
Profile::CreateStatus::CREATE_STATUS_INITIALIZED),
|
|
|
|
base::BindOnce(&ChromeBrowserContext::ProfileCreated,
|
|
|
|
weak_ptr_factory_.GetWeakPtr(),
|
|
|
|
Profile::CreateStatus::CREATE_STATUS_CREATED));
|
2021-04-07 00:09:45 +02:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
// All profile directories must be relative to |user_data_dir|.
|
|
|
|
LOG(ERROR) << "Cannot create profile at path "
|
|
|
|
<< cache_path_.AsUTF8Unsafe();
|
|
|
|
}
|
|
|
|
}
|
2020-09-25 03:40:47 +02:00
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
// Default to creating a new/unique OffTheRecord profile.
|
2022-09-26 21:30:45 +02:00
|
|
|
ProfileCreated(Profile::CreateStatus::CREATE_STATUS_LOCAL_FAIL, nullptr);
|
2020-07-04 04:51:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ChromeBrowserContext::Shutdown() {
|
|
|
|
CefBrowserContext::Shutdown();
|
2021-07-23 21:55:22 +02:00
|
|
|
|
|
|
|
// Allow potential deletion of the Profile at some future point (controlled
|
|
|
|
// by ProfileManager).
|
|
|
|
profile_keep_alive_.reset();
|
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
// |g_browser_process| may be nullptr during shutdown.
|
2021-07-23 21:55:22 +02:00
|
|
|
if (g_browser_process) {
|
|
|
|
if (should_destroy_) {
|
2023-01-03 00:34:43 +01:00
|
|
|
GetPrimaryUserProfile()->DestroyOffTheRecordProfile(profile_);
|
2021-07-23 21:55:22 +02:00
|
|
|
} else if (profile_) {
|
|
|
|
OnProfileWillBeDestroyed(profile_);
|
|
|
|
}
|
2021-04-07 00:09:45 +02:00
|
|
|
}
|
2020-07-04 04:51:17 +02:00
|
|
|
}
|
2021-04-07 00:09:45 +02:00
|
|
|
|
2022-09-26 21:30:45 +02:00
|
|
|
void ChromeBrowserContext::ProfileCreated(Profile::CreateStatus status,
|
|
|
|
Profile* profile) {
|
2021-04-09 20:34:45 +02:00
|
|
|
Profile* parent_profile = nullptr;
|
|
|
|
OffTheRecordProfileImpl* otr_profile = nullptr;
|
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
if (status != Profile::CreateStatus::CREATE_STATUS_CREATED &&
|
|
|
|
status != Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
2021-04-15 19:34:22 +02:00
|
|
|
CHECK(!profile);
|
|
|
|
CHECK(!profile_);
|
2021-04-07 00:09:45 +02:00
|
|
|
|
2021-08-04 21:19:00 +02:00
|
|
|
// Profile creation may access the filesystem.
|
|
|
|
base::ScopedAllowBlockingForTesting allow_blocking;
|
|
|
|
|
2021-04-07 00:09:45 +02:00
|
|
|
// Creation of a disk-based profile failed for some reason. Create a
|
|
|
|
// new/unique OffTheRecord profile instead.
|
|
|
|
const auto& profile_id = Profile::OTRProfileID::CreateUniqueForCEF();
|
2023-01-03 00:34:43 +01:00
|
|
|
parent_profile = GetPrimaryUserProfile();
|
2021-06-04 03:34:56 +02:00
|
|
|
profile_ = parent_profile->GetOffTheRecordProfile(
|
|
|
|
profile_id, /*create_if_needed=*/true);
|
2021-04-09 20:34:45 +02:00
|
|
|
otr_profile = static_cast<OffTheRecordProfileImpl*>(profile_);
|
2021-04-07 00:09:45 +02:00
|
|
|
status = Profile::CreateStatus::CREATE_STATUS_INITIALIZED;
|
|
|
|
should_destroy_ = true;
|
2021-04-15 19:34:22 +02:00
|
|
|
} else if (profile && !profile_) {
|
|
|
|
// May be CREATE_STATUS_CREATED or CREATE_STATUS_INITIALIZED since
|
|
|
|
// *CREATED isn't always sent for a disk-based profile that already
|
|
|
|
// exists.
|
|
|
|
profile_ = profile;
|
2021-07-23 21:55:22 +02:00
|
|
|
profile_->AddObserver(this);
|
|
|
|
profile_keep_alive_.reset(new ScopedProfileKeepAlive(
|
|
|
|
profile_, ProfileKeepAliveOrigin::kAppWindow));
|
2021-04-07 00:09:45 +02:00
|
|
|
}
|
|
|
|
|
2021-04-15 19:34:22 +02:00
|
|
|
if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) {
|
|
|
|
CHECK(profile_);
|
2021-04-07 00:09:45 +02:00
|
|
|
|
2021-04-09 20:34:45 +02:00
|
|
|
// Must set |profile_| before Init() calls
|
|
|
|
// ChromeContentBrowserClientCef::ConfigureNetworkContextParams so that
|
|
|
|
// CefBrowserContext::FromBrowserContext can find us.
|
|
|
|
if (otr_profile) {
|
|
|
|
otr_profile->Init();
|
|
|
|
parent_profile->NotifyOffTheRecordProfileCreated(otr_profile);
|
|
|
|
}
|
|
|
|
|
2022-03-23 01:42:03 +01:00
|
|
|
if (!profile_->IsOffTheRecord()) {
|
|
|
|
// Configure the desired profile restore behavior for the next application
|
|
|
|
// restart (checked via ProfileImpl::ShouldRestoreOldSessionCookies).
|
|
|
|
profile_->GetPrefs()->SetInteger(
|
|
|
|
prefs::kRestoreOnStartup, !!settings_.persist_session_cookies
|
|
|
|
? SessionStartupPref::kPrefValueLast
|
|
|
|
: SessionStartupPref::kPrefValueNewTab);
|
|
|
|
}
|
|
|
|
|
2021-04-15 01:28:22 +02:00
|
|
|
if (!init_callbacks_.empty()) {
|
|
|
|
for (auto& callback : init_callbacks_) {
|
|
|
|
std::move(callback).Run();
|
|
|
|
}
|
|
|
|
init_callbacks_.clear();
|
|
|
|
}
|
2021-04-07 00:09:45 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-23 21:55:22 +02:00
|
|
|
|
|
|
|
void ChromeBrowserContext::OnProfileWillBeDestroyed(Profile* profile) {
|
|
|
|
CHECK_EQ(profile_, profile);
|
|
|
|
profile_->RemoveObserver(this);
|
|
|
|
profile_ = nullptr;
|
|
|
|
destroyed_ = true;
|
|
|
|
}
|