1 // Copyright 2013 The Chromium 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 "content/shell/browser/shell_browser_context.h"
6 
7 #include <utility>
8 
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/environment.h"
12 #include "base/files/file_util.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/threading/thread.h"
16 #include "build/build_config.h"
17 #include "components/keyed_service/content/browser_context_dependency_manager.h"
18 #include "components/keyed_service/core/simple_dependency_manager.h"
19 #include "components/keyed_service/core/simple_factory_key.h"
20 #include "components/keyed_service/core/simple_key_map.h"
21 #include "components/network_session_configurator/common/network_switches.h"
22 #include "content/public/browser/browser_task_traits.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/storage_partition.h"
25 #include "content/public/common/content_switches.h"
26 #include "content/shell/browser/shell_content_index_provider.h"
27 #include "content/shell/browser/shell_download_manager_delegate.h"
28 #include "content/shell/browser/shell_permission_manager.h"
29 #include "content/shell/common/shell_switches.h"
30 #include "content/test/mock_background_sync_controller.h"
31 
32 #if defined(OS_WIN)
33 #include "base/base_paths_win.h"
34 #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
35 #include "base/nix/xdg_util.h"
36 #elif defined(OS_MAC)
37 #include "base/base_paths_mac.h"
38 #elif defined(OS_FUCHSIA)
39 #include "base/base_paths_fuchsia.h"
40 #endif
41 
42 namespace content {
43 
ShellResourceContext()44 ShellBrowserContext::ShellResourceContext::ShellResourceContext() {}
45 
~ShellResourceContext()46 ShellBrowserContext::ShellResourceContext::~ShellResourceContext() {
47 }
48 
ShellBrowserContext(bool off_the_record,bool delay_services_creation)49 ShellBrowserContext::ShellBrowserContext(bool off_the_record,
50                                          bool delay_services_creation)
51     : resource_context_(std::make_unique<ShellResourceContext>()),
52       off_the_record_(off_the_record) {
53   InitWhileIOAllowed();
54   if (!delay_services_creation) {
55     BrowserContextDependencyManager::GetInstance()
56         ->CreateBrowserContextServices(this);
57   }
58 }
59 
~ShellBrowserContext()60 ShellBrowserContext::~ShellBrowserContext() {
61   NotifyWillBeDestroyed(this);
62 
63   // The SimpleDependencyManager should always be passed after the
64   // BrowserContextDependencyManager. This is because the KeyedService instances
65   // in the BrowserContextDependencyManager's dependency graph can depend on the
66   // ones in the SimpleDependencyManager's graph.
67   DependencyManager::PerformInterlockedTwoPhaseShutdown(
68       BrowserContextDependencyManager::GetInstance(), this,
69       SimpleDependencyManager::GetInstance(), key_.get());
70 
71   SimpleKeyMap::GetInstance()->Dissociate(this);
72 
73   // Need to destruct the ResourceContext before posting tasks which may delete
74   // the URLRequestContext because ResourceContext's destructor will remove any
75   // outstanding request while URLRequestContext's destructor ensures that there
76   // are no more outstanding requests.
77   if (resource_context_) {
78     GetIOThreadTaskRunner({})->DeleteSoon(FROM_HERE,
79                                           resource_context_.release());
80   }
81   ShutdownStoragePartitions();
82 }
83 
InitWhileIOAllowed()84 void ShellBrowserContext::InitWhileIOAllowed() {
85   base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
86   if (cmd_line->HasSwitch(switches::kIgnoreCertificateErrors))
87     ignore_certificate_errors_ = true;
88   if (cmd_line->HasSwitch(switches::kContentShellDataPath)) {
89     path_ = cmd_line->GetSwitchValuePath(switches::kContentShellDataPath);
90     if (base::DirectoryExists(path_) || base::CreateDirectory(path_))  {
91       // BrowserContext needs an absolute path, which we would normally get via
92       // PathService. In this case, manually ensure the path is absolute.
93       if (!path_.IsAbsolute())
94         path_ = base::MakeAbsoluteFilePath(path_);
95       if (!path_.empty()) {
96         FinishInitWhileIOAllowed();
97         return;
98       }
99     } else {
100       LOG(WARNING) << "Unable to create data-path directory: " << path_.value();
101     }
102   }
103 
104 #if defined(OS_WIN)
105   CHECK(base::PathService::Get(base::DIR_LOCAL_APP_DATA, &path_));
106   path_ = path_.Append(std::wstring(L"content_shell"));
107 #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD)
108   std::unique_ptr<base::Environment> env(base::Environment::Create());
109   base::FilePath config_dir(
110       base::nix::GetXDGDirectory(env.get(),
111                                  base::nix::kXdgConfigHomeEnvVar,
112                                  base::nix::kDotConfigDir));
113   path_ = config_dir.Append("content_shell");
114 #elif defined(OS_MAC)
115   CHECK(base::PathService::Get(base::DIR_APP_DATA, &path_));
116   path_ = path_.Append("Chromium Content Shell");
117 #elif defined(OS_ANDROID)
118   CHECK(base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path_));
119   path_ = path_.Append(FILE_PATH_LITERAL("content_shell"));
120 #elif defined(OS_FUCHSIA)
121   CHECK(base::PathService::Get(base::DIR_APP_DATA, &path_));
122   path_ = path_.Append(FILE_PATH_LITERAL("content_shell"));
123 #else
124   NOTIMPLEMENTED();
125 #endif
126 
127   if (!base::PathExists(path_))
128     base::CreateDirectory(path_);
129 
130   FinishInitWhileIOAllowed();
131 }
132 
FinishInitWhileIOAllowed()133 void ShellBrowserContext::FinishInitWhileIOAllowed() {
134   key_ = std::make_unique<SimpleFactoryKey>(path_, off_the_record_);
135   SimpleKeyMap::GetInstance()->Associate(this, key_.get());
136 }
137 
138 #if !defined(OS_ANDROID)
CreateZoomLevelDelegate(const base::FilePath &)139 std::unique_ptr<ZoomLevelDelegate> ShellBrowserContext::CreateZoomLevelDelegate(
140     const base::FilePath&) {
141   return std::unique_ptr<ZoomLevelDelegate>();
142 }
143 #endif  // !defined(OS_ANDROID)
144 
GetPath()145 base::FilePath ShellBrowserContext::GetPath() {
146   return path_;
147 }
148 
IsOffTheRecord()149 bool ShellBrowserContext::IsOffTheRecord() {
150   return off_the_record_;
151 }
152 
GetDownloadManagerDelegate()153 DownloadManagerDelegate* ShellBrowserContext::GetDownloadManagerDelegate()  {
154   if (!download_manager_delegate_.get()) {
155     download_manager_delegate_.reset(new ShellDownloadManagerDelegate());
156     download_manager_delegate_->SetDownloadManager(
157         BrowserContext::GetDownloadManager(this));
158   }
159 
160   return download_manager_delegate_.get();
161 }
162 
GetResourceContext()163 ResourceContext* ShellBrowserContext::GetResourceContext()  {
164   return resource_context_.get();
165 }
166 
GetGuestManager()167 BrowserPluginGuestManager* ShellBrowserContext::GetGuestManager() {
168   return nullptr;
169 }
170 
GetSpecialStoragePolicy()171 storage::SpecialStoragePolicy* ShellBrowserContext::GetSpecialStoragePolicy() {
172   return nullptr;
173 }
174 
GetPushMessagingService()175 PushMessagingService* ShellBrowserContext::GetPushMessagingService() {
176   return nullptr;
177 }
178 
179 StorageNotificationService*
GetStorageNotificationService()180 ShellBrowserContext::GetStorageNotificationService() {
181   return nullptr;
182 }
183 
GetSSLHostStateDelegate()184 SSLHostStateDelegate* ShellBrowserContext::GetSSLHostStateDelegate() {
185   return nullptr;
186 }
187 
188 PermissionControllerDelegate*
GetPermissionControllerDelegate()189 ShellBrowserContext::GetPermissionControllerDelegate() {
190   if (!permission_manager_.get())
191     permission_manager_.reset(new ShellPermissionManager());
192   return permission_manager_.get();
193 }
194 
195 ClientHintsControllerDelegate*
GetClientHintsControllerDelegate()196 ShellBrowserContext::GetClientHintsControllerDelegate() {
197   return client_hints_controller_delegate_;
198 }
199 
GetBackgroundFetchDelegate()200 BackgroundFetchDelegate* ShellBrowserContext::GetBackgroundFetchDelegate() {
201   return nullptr;
202 }
203 
GetBackgroundSyncController()204 BackgroundSyncController* ShellBrowserContext::GetBackgroundSyncController() {
205   if (!background_sync_controller_)
206     background_sync_controller_.reset(new MockBackgroundSyncController());
207   return background_sync_controller_.get();
208 }
209 
210 BrowsingDataRemoverDelegate*
GetBrowsingDataRemoverDelegate()211 ShellBrowserContext::GetBrowsingDataRemoverDelegate() {
212   return nullptr;
213 }
214 
GetContentIndexProvider()215 ContentIndexProvider* ShellBrowserContext::GetContentIndexProvider() {
216   if (!content_index_provider_)
217     content_index_provider_ = std::make_unique<ShellContentIndexProvider>();
218   return content_index_provider_.get();
219 }
220 
221 }  // namespace content
222