1 // Copyright 2020 The Chromium Embedded Framework 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 5 #include "libcef/browser/chrome/chrome_browser_context.h" 6 7 #include "libcef/browser/thread_util.h" 8 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/profiles/off_the_record_profile_impl.h" 11 ChromeBrowserContext(const CefRequestContextSettings & settings)12ChromeBrowserContext::ChromeBrowserContext( 13 const CefRequestContextSettings& settings) 14 : CefBrowserContext(settings), weak_ptr_factory_(this) {} 15 16 ChromeBrowserContext::~ChromeBrowserContext() = default; 17 AsBrowserContext()18content::BrowserContext* ChromeBrowserContext::AsBrowserContext() { 19 return profile_; 20 } 21 AsProfile()22Profile* ChromeBrowserContext::AsProfile() { 23 return profile_; 24 } 25 IsInitialized() const26bool ChromeBrowserContext::IsInitialized() const { 27 CEF_REQUIRE_UIT(); 28 return !!profile_; 29 } 30 StoreOrTriggerInitCallback(base::OnceClosure callback)31void ChromeBrowserContext::StoreOrTriggerInitCallback( 32 base::OnceClosure callback) { 33 CEF_REQUIRE_UIT(); 34 if (IsInitialized()) { 35 std::move(callback).Run(); 36 } else { 37 init_callbacks_.emplace_back(std::move(callback)); 38 } 39 } 40 InitializeAsync(base::OnceClosure initialized_cb)41void ChromeBrowserContext::InitializeAsync(base::OnceClosure initialized_cb) { 42 init_callbacks_.emplace_back(std::move(initialized_cb)); 43 44 CefBrowserContext::Initialize(); 45 46 if (!cache_path_.empty()) { 47 auto* profile_manager = g_browser_process->profile_manager(); 48 const auto& user_data_dir = profile_manager->user_data_dir(); 49 50 if (cache_path_ == user_data_dir) { 51 // Use the default disk-based profile. 52 auto profile = profile_manager->GetPrimaryUserProfile(); 53 ProfileCreated(profile, Profile::CreateStatus::CREATE_STATUS_INITIALIZED); 54 return; 55 } else if (cache_path_.DirName() == user_data_dir) { 56 // Create or load a specific disk-based profile. May continue 57 // synchronously or asynchronously. 58 profile_manager->CreateProfileAsync( 59 cache_path_, base::Bind(&ChromeBrowserContext::ProfileCreated, 60 weak_ptr_factory_.GetWeakPtr())); 61 return; 62 } else { 63 // All profile directories must be relative to |user_data_dir|. 64 LOG(ERROR) << "Cannot create profile at path " 65 << cache_path_.AsUTF8Unsafe(); 66 } 67 } 68 69 // Default to creating a new/unique OffTheRecord profile. 70 ProfileCreated(nullptr, Profile::CreateStatus::CREATE_STATUS_CANCELED); 71 } 72 Shutdown()73void ChromeBrowserContext::Shutdown() { 74 CefBrowserContext::Shutdown(); 75 // |g_browser_process| may be nullptr during shutdown. 76 if (should_destroy_ && g_browser_process) { 77 g_browser_process->profile_manager() 78 ->GetPrimaryUserProfile() 79 ->DestroyOffTheRecordProfile(profile_); 80 } 81 profile_ = nullptr; 82 } 83 ProfileCreated(Profile * profile,Profile::CreateStatus status)84void ChromeBrowserContext::ProfileCreated(Profile* profile, 85 Profile::CreateStatus status) { 86 Profile* parent_profile = nullptr; 87 OffTheRecordProfileImpl* otr_profile = nullptr; 88 89 if (status != Profile::CreateStatus::CREATE_STATUS_CREATED && 90 status != Profile::CreateStatus::CREATE_STATUS_INITIALIZED) { 91 CHECK(!profile); 92 CHECK(!profile_); 93 94 // Creation of a disk-based profile failed for some reason. Create a 95 // new/unique OffTheRecord profile instead. 96 const auto& profile_id = Profile::OTRProfileID::CreateUniqueForCEF(); 97 parent_profile = 98 g_browser_process->profile_manager()->GetPrimaryUserProfile(); 99 profile_ = parent_profile->GetOffTheRecordProfile(profile_id); 100 otr_profile = static_cast<OffTheRecordProfileImpl*>(profile_); 101 status = Profile::CreateStatus::CREATE_STATUS_INITIALIZED; 102 should_destroy_ = true; 103 } else if (profile && !profile_) { 104 // May be CREATE_STATUS_CREATED or CREATE_STATUS_INITIALIZED since 105 // *CREATED isn't always sent for a disk-based profile that already 106 // exists. 107 profile_ = profile; 108 } 109 110 if (status == Profile::CreateStatus::CREATE_STATUS_INITIALIZED) { 111 CHECK(profile_); 112 113 // Must set |profile_| before Init() calls 114 // ChromeContentBrowserClientCef::ConfigureNetworkContextParams so that 115 // CefBrowserContext::FromBrowserContext can find us. 116 if (otr_profile) { 117 otr_profile->Init(); 118 parent_profile->NotifyOffTheRecordProfileCreated(otr_profile); 119 } 120 121 if (!init_callbacks_.empty()) { 122 for (auto& callback : init_callbacks_) { 123 std::move(callback).Run(); 124 } 125 init_callbacks_.clear(); 126 } 127 } 128 } 129