Home | History | Annotate | Download | only in shell
      1 // Copyright (c) 2012 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/shell_content_browser_client.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/file_util.h"
      9 #include "base/path_service.h"
     10 #include "content/public/browser/notification_service.h"
     11 #include "content/public/browser/notification_types.h"
     12 #include "content/public/browser/render_process_host.h"
     13 #include "content/public/browser/resource_dispatcher_host.h"
     14 #include "content/public/browser/storage_partition.h"
     15 #include "content/public/common/content_switches.h"
     16 #include "content/public/common/url_constants.h"
     17 #include "content/shell/common/shell_messages.h"
     18 #include "content/shell/common/shell_switches.h"
     19 #include "content/shell/common/webkit_test_helpers.h"
     20 #include "content/shell/geolocation/shell_access_token_store.h"
     21 #include "content/shell/shell.h"
     22 #include "content/shell/shell_browser_context.h"
     23 #include "content/shell/shell_browser_main_parts.h"
     24 #include "content/shell/shell_devtools_delegate.h"
     25 #include "content/shell/shell_message_filter.h"
     26 #include "content/shell/shell_net_log.h"
     27 #include "content/shell/shell_quota_permission_context.h"
     28 #include "content/shell/shell_resource_dispatcher_host_delegate.h"
     29 #include "content/shell/shell_web_contents_view_delegate_creator.h"
     30 #include "content/shell/webkit_test_controller.h"
     31 #include "net/url_request/url_request_context_getter.h"
     32 #include "url/gurl.h"
     33 #include "webkit/common/webpreferences.h"
     34 
     35 #if defined(OS_ANDROID)
     36 #include "base/android/path_utils.h"
     37 #include "base/path_service.h"
     38 #include "base/platform_file.h"
     39 #include "content/shell/android/shell_descriptors.h"
     40 #endif
     41 
     42 namespace content {
     43 
     44 namespace {
     45 
     46 ShellContentBrowserClient* g_browser_client;
     47 bool g_swap_processes_for_redirect = false;
     48 
     49 }  // namespace
     50 
     51 ShellContentBrowserClient* ShellContentBrowserClient::Get() {
     52   return g_browser_client;
     53 }
     54 
     55 void ShellContentBrowserClient::SetSwapProcessesForRedirect(bool swap) {
     56   g_swap_processes_for_redirect = swap;
     57 }
     58 
     59 ShellContentBrowserClient::ShellContentBrowserClient()
     60     : shell_browser_main_parts_(NULL) {
     61   DCHECK(!g_browser_client);
     62   g_browser_client = this;
     63   if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
     64     return;
     65   webkit_source_dir_ = GetWebKitRootDirFilePath();
     66 }
     67 
     68 ShellContentBrowserClient::~ShellContentBrowserClient() {
     69   g_browser_client = NULL;
     70 }
     71 
     72 BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
     73     const MainFunctionParams& parameters) {
     74   shell_browser_main_parts_ = new ShellBrowserMainParts(parameters);
     75   return shell_browser_main_parts_;
     76 }
     77 
     78 void ShellContentBrowserClient::RenderProcessHostCreated(
     79     RenderProcessHost* host) {
     80   if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
     81     return;
     82   host->GetChannel()->AddFilter(new ShellMessageFilter(
     83       host->GetID(),
     84       BrowserContext::GetDefaultStoragePartition(browser_context())
     85           ->GetDatabaseTracker(),
     86       BrowserContext::GetDefaultStoragePartition(browser_context())
     87           ->GetQuotaManager(),
     88       BrowserContext::GetDefaultStoragePartition(browser_context())
     89           ->GetURLRequestContext()));
     90   host->Send(new ShellViewMsg_SetWebKitSourceDir(webkit_source_dir_));
     91   registrar_.Add(this,
     92                  NOTIFICATION_RENDERER_PROCESS_CREATED,
     93                  Source<RenderProcessHost>(host));
     94   registrar_.Add(this,
     95                  NOTIFICATION_RENDERER_PROCESS_TERMINATED,
     96                  Source<RenderProcessHost>(host));
     97 }
     98 
     99 net::URLRequestContextGetter* ShellContentBrowserClient::CreateRequestContext(
    100     BrowserContext* content_browser_context,
    101     ProtocolHandlerMap* protocol_handlers) {
    102   ShellBrowserContext* shell_browser_context =
    103       ShellBrowserContextForBrowserContext(content_browser_context);
    104   return shell_browser_context->CreateRequestContext(protocol_handlers);
    105 }
    106 
    107 net::URLRequestContextGetter*
    108 ShellContentBrowserClient::CreateRequestContextForStoragePartition(
    109     BrowserContext* content_browser_context,
    110     const base::FilePath& partition_path,
    111     bool in_memory,
    112     ProtocolHandlerMap* protocol_handlers) {
    113   ShellBrowserContext* shell_browser_context =
    114       ShellBrowserContextForBrowserContext(content_browser_context);
    115   return shell_browser_context->CreateRequestContextForStoragePartition(
    116       partition_path, in_memory, protocol_handlers);
    117 }
    118 
    119 bool ShellContentBrowserClient::IsHandledURL(const GURL& url) {
    120   if (!url.is_valid())
    121     return false;
    122   DCHECK_EQ(url.scheme(), StringToLowerASCII(url.scheme()));
    123   // Keep in sync with ProtocolHandlers added by
    124   // ShellURLRequestContextGetter::GetURLRequestContext().
    125   static const char* const kProtocolList[] = {
    126       chrome::kBlobScheme,
    127       chrome::kFileSystemScheme,
    128       chrome::kChromeUIScheme,
    129       chrome::kChromeDevToolsScheme,
    130       chrome::kDataScheme,
    131       chrome::kFileScheme,
    132   };
    133   for (size_t i = 0; i < arraysize(kProtocolList); ++i) {
    134     if (url.scheme() == kProtocolList[i])
    135       return true;
    136   }
    137   return false;
    138 }
    139 
    140 void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
    141     CommandLine* command_line, int child_process_id) {
    142   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
    143     command_line->AppendSwitch(switches::kDumpRenderTree);
    144   if (CommandLine::ForCurrentProcess()->HasSwitch(
    145       switches::kExposeInternalsForTesting))
    146     command_line->AppendSwitch(switches::kExposeInternalsForTesting);
    147 }
    148 
    149 void ShellContentBrowserClient::OverrideWebkitPrefs(
    150     RenderViewHost* render_view_host,
    151     const GURL& url,
    152     WebPreferences* prefs) {
    153   if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
    154     return;
    155   WebKitTestController::Get()->OverrideWebkitPrefs(prefs);
    156 }
    157 
    158 void ShellContentBrowserClient::ResourceDispatcherHostCreated() {
    159   resource_dispatcher_host_delegate_.reset(
    160       new ShellResourceDispatcherHostDelegate());
    161   ResourceDispatcherHost::Get()->SetDelegate(
    162       resource_dispatcher_host_delegate_.get());
    163 }
    164 
    165 std::string ShellContentBrowserClient::GetDefaultDownloadName() {
    166   return "download";
    167 }
    168 
    169 bool ShellContentBrowserClient::SupportsBrowserPlugin(
    170     content::BrowserContext* browser_context, const GURL& url) {
    171   return CommandLine::ForCurrentProcess()->HasSwitch(
    172       switches::kEnableBrowserPluginForAllViewTypes);
    173 }
    174 
    175 WebContentsViewDelegate* ShellContentBrowserClient::GetWebContentsViewDelegate(
    176     WebContents* web_contents) {
    177 #if !defined(USE_AURA)
    178   return CreateShellWebContentsViewDelegate(web_contents);
    179 #else
    180   return NULL;
    181 #endif
    182 }
    183 
    184 QuotaPermissionContext*
    185 ShellContentBrowserClient::CreateQuotaPermissionContext() {
    186   return new ShellQuotaPermissionContext();
    187 }
    188 
    189 net::NetLog* ShellContentBrowserClient::GetNetLog() {
    190   return shell_browser_main_parts_->net_log();
    191 }
    192 
    193 bool ShellContentBrowserClient::ShouldSwapProcessesForRedirect(
    194     ResourceContext* resource_context,
    195     const GURL& current_url,
    196     const GURL& new_url) {
    197   return g_swap_processes_for_redirect;
    198 }
    199 
    200 #if defined(OS_ANDROID)
    201 void ShellContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
    202     const CommandLine& command_line,
    203     int child_process_id,
    204     std::vector<content::FileDescriptorInfo>* mappings) {
    205   int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
    206   base::FilePath pak_file;
    207   bool r = PathService::Get(base::DIR_ANDROID_APP_DATA, &pak_file);
    208   CHECK(r);
    209   pak_file = pak_file.Append(FILE_PATH_LITERAL("paks"));
    210   pak_file = pak_file.Append(FILE_PATH_LITERAL("content_shell.pak"));
    211 
    212   base::PlatformFile f =
    213       base::CreatePlatformFile(pak_file, flags, NULL, NULL);
    214   if (f == base::kInvalidPlatformFileValue) {
    215     NOTREACHED() << "Failed to open file when creating renderer process: "
    216                  << "content_shell.pak";
    217   }
    218   mappings->push_back(
    219       content::FileDescriptorInfo(kShellPakDescriptor,
    220                                   base::FileDescriptor(f, true)));
    221 }
    222 #endif
    223 
    224 void ShellContentBrowserClient::Observe(int type,
    225                                         const NotificationSource& source,
    226                                         const NotificationDetails& details) {
    227   switch (type) {
    228     case NOTIFICATION_RENDERER_PROCESS_CREATED: {
    229       registrar_.Remove(this,
    230                         NOTIFICATION_RENDERER_PROCESS_CREATED,
    231                         source);
    232       registrar_.Remove(this,
    233                         NOTIFICATION_RENDERER_PROCESS_TERMINATED,
    234                         source);
    235       break;
    236     }
    237 
    238     case NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
    239       registrar_.Remove(this,
    240                         NOTIFICATION_RENDERER_PROCESS_CREATED,
    241                         source);
    242       registrar_.Remove(this,
    243                         NOTIFICATION_RENDERER_PROCESS_TERMINATED,
    244                         source);
    245       break;
    246     }
    247 
    248     default:
    249       NOTREACHED();
    250   }
    251 }
    252 
    253 ShellBrowserContext* ShellContentBrowserClient::browser_context() {
    254   return shell_browser_main_parts_->browser_context();
    255 }
    256 
    257 ShellBrowserContext*
    258     ShellContentBrowserClient::off_the_record_browser_context() {
    259   return shell_browser_main_parts_->off_the_record_browser_context();
    260 }
    261 
    262 AccessTokenStore* ShellContentBrowserClient::CreateAccessTokenStore() {
    263   return new ShellAccessTokenStore(browser_context());
    264 }
    265 
    266 ShellBrowserContext*
    267 ShellContentBrowserClient::ShellBrowserContextForBrowserContext(
    268     BrowserContext* content_browser_context) {
    269   if (content_browser_context == browser_context())
    270     return browser_context();
    271   DCHECK_EQ(content_browser_context, off_the_record_browser_context());
    272   return off_the_record_browser_context();
    273 }
    274 
    275 }  // namespace content
    276