• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)12 ChromeBrowserContext::ChromeBrowserContext(
13     const CefRequestContextSettings& settings)
14     : CefBrowserContext(settings), weak_ptr_factory_(this) {}
15 
16 ChromeBrowserContext::~ChromeBrowserContext() = default;
17 
AsBrowserContext()18 content::BrowserContext* ChromeBrowserContext::AsBrowserContext() {
19   return profile_;
20 }
21 
AsProfile()22 Profile* ChromeBrowserContext::AsProfile() {
23   return profile_;
24 }
25 
IsInitialized() const26 bool ChromeBrowserContext::IsInitialized() const {
27   CEF_REQUIRE_UIT();
28   return !!profile_;
29 }
30 
StoreOrTriggerInitCallback(base::OnceClosure callback)31 void 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)41 void 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()73 void 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)84 void 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