15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/chrome_render_process_observer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <limits>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/allocator_extension.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/field_trial.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/native_library.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/utf_string_conversions.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/child_process_logging.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/net/net_resource_provider.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/render_messages.h"
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/url_constants.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/variations/variations_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/content_settings_observer.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/security_filter_peer.h"
32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/child/resource_dispatcher_delegate.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_thread.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
359ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "content/public/renderer/render_view_visitor.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/nss_util.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_module.h"
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebCache.h"
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h"
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/iat_patch_function.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS)
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/renderer/extensions/extension_localization_peer.h"
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebCache;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebRuntimeFeatures;
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebSecurityPolicy;
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebString;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderThread;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kCacheStatsDelayMS = 2000;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RendererResourceDelegate : public content::ResourceDispatcherDelegate {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RendererResourceDelegate()
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : weak_factory_(this) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual content::RequestPeer* OnRequestComplete(
71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      content::RequestPeer* current_peer,
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::ResourceType resource_type,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int error_code) OVERRIDE {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update the browser about our cache.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Rate limit informing the host of our cache stats.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!weak_factory_.HasWeakPtrs()) {
77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      base::MessageLoop::current()->PostDelayedTask(
78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          FROM_HERE,
79a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          base::Bind(&RendererResourceDelegate::InformHostOfCacheStats,
80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                     weak_factory_.GetWeakPtr()),
81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          base::TimeDelta::FromMilliseconds(kCacheStatsDelayMS));
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error_code == net::ERR_ABORTED) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resource canceled with a specific error are filtered.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest(
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        resource_type, current_peer, error_code);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  virtual content::RequestPeer* OnReceivedResponse(
94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      content::RequestPeer* current_peer,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& mime_type,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& url) OVERRIDE {
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_peer, RenderThread::Get(), mime_type, url);
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return NULL;
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InformHostOfCacheStats() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebCache::UsageStats stats;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebCache::getUsageStats(&stats);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderThread::Get()->Send(new ChromeViewHostMsg_UpdatedCacheStats(stats));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<RendererResourceDelegate> weak_factory_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::win::IATPatchFunction g_iat_patch_createdca;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LPCSTR device_name,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          LPCSTR output,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const void* init_data) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(std::string("DISPLAY") == std::string(driver_name));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!device_name);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!output);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!init_data);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CreateDC fails behind the sandbox, but not CreateCompatibleDC.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateCompatibleDC(NULL);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::win::IATPatchFunction g_iat_patch_get_font_data;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD WINAPI GetFontDataPatch(HDC hdc,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD table,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD offset,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              LPVOID buffer,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DWORD length) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = GetFontData(hdc, table, offset, buffer, length);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == GDI_ERROR && hdc) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOGFONT logfont;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GetObject(font, sizeof(LOGFONT), &logfont)) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<char> font_data;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderThread::Get()->PreCacheFont(logfont);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rv = GetFontData(hdc, table, offset, buffer, length);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RenderThread::Get()->ReleaseCachedFonts();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // OS_WIN
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)static const int kWaitForWorkersStatsTimeoutMS = 20;
1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HeapStatisticsCollector {
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HeapStatisticsCollector() : round_id_(0) {}
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void InitiateCollection();
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  static HeapStatisticsCollector* Instance();
1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void CollectOnWorkerThread(scoped_refptr<base::TaskRunner> master,
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                             int round_id);
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ReceiveStats(int round_id, size_t total_size, size_t used_size);
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void SendStatsToBrowser(int round_id);
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t total_bytes_;
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t used_bytes_;
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int workers_to_go_;
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int round_id_;
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)HeapStatisticsCollector* HeapStatisticsCollector::Instance() {
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CR_DEFINE_STATIC_LOCAL(HeapStatisticsCollector, instance, ());
1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return &instance;
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HeapStatisticsCollector::InitiateCollection() {
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v8::HeapStatistics heap_stats;
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  total_bytes_ = heap_stats.total_heap_size();
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  used_bytes_ = heap_stats.used_heap_size();
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::Closure collect = base::Bind(
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      &HeapStatisticsCollector::CollectOnWorkerThread,
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Unretained(this),
1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::MessageLoopProxy::current(),
1897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      round_id_);
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  workers_to_go_ = RenderThread::Get()->PostTaskToAllWebWorkers(collect);
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (workers_to_go_) {
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // The guard task to send out partial stats
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // in case some workers are not responsive.
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::MessageLoopProxy::current()->PostDelayedTask(
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        FROM_HERE,
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&HeapStatisticsCollector::SendStatsToBrowser,
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   base::Unretained(this),
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                   round_id_),
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // No worker threads so just send out the main thread data right away.
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SendStatsToBrowser(round_id_);
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HeapStatisticsCollector::CollectOnWorkerThread(
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scoped_refptr<base::TaskRunner> master,
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int round_id) {
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t total_bytes = 0;
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  size_t used_bytes = 0;
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  v8::Isolate* isolate = v8::Isolate::GetCurrent();
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (isolate) {
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    v8::HeapStatistics heap_stats;
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    isolate->GetHeapStatistics(&heap_stats);
2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    total_bytes = heap_stats.total_heap_size();
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    used_bytes = heap_stats.used_heap_size();
2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  master->PostTask(
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      FROM_HERE,
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Bind(&HeapStatisticsCollector::ReceiveStats,
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 base::Unretained(this),
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 round_id,
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 total_bytes,
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                 used_bytes));
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HeapStatisticsCollector::ReceiveStats(int round_id,
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                           size_t total_bytes,
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                           size_t used_bytes) {
2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (round_id != round_id_)
2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  total_bytes_ += total_bytes;
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  used_bytes_ += used_bytes;
2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!--workers_to_go_)
2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SendStatsToBrowser(round_id);
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HeapStatisticsCollector::SendStatsToBrowser(int round_id) {
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (round_id != round_id_)
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // TODO(alph): Do caching heap stats and use the cache if we haven't got
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //             reply from a worker.
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  //             Currently a busy worker stats are not counted.
2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  RenderThread::Get()->Send(new ChromeViewHostMsg_V8HeapStats(
2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      total_bytes_, used_bytes_));
2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ++round_id_;
2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeRenderProcessObserver::is_incognito_process_ = false;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeRenderProcessObserver::ChromeRenderProcessObserver(
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ChromeContentRendererClient* client)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : client_(client),
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      webkit_initialized_(false) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_AUTOFILL_DIALOG)
261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WebRuntimeFeatures::enableRequestAutocomplete(true);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (command_line.HasSwitch(switches::kEnableShowModalDialog))
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    WebRuntimeFeatures::enableShowModalDialog(true);
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (command_line.HasSwitch(switches::kJavaScriptHarmony)) {
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string flag("--harmony");
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    v8::V8::SetFlagsFromString(flag.c_str(), static_cast<int>(flag.size()));
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThread* thread = RenderThread::Get();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_delegate_.reset(new RendererResourceDelegate());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  thread->SetResourceDispatcherDelegate(resource_delegate_.get());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure modules that need access to resources.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to patch a few functions for font loading to work correctly.
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pdf;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) &&
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::PathExists(pdf)) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_iat_patch_createdca.Patch(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_iat_patch_get_font_data.Patch(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pdf.value().c_str(), "gdi32.dll", "GetFontData", GetFontDataPatch);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_NSS)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On platforms where we use system NSS shared libraries,
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // initialize NSS now because it won't be able to load the .so's
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // after we engage the sandbox.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line.HasSwitch(switches::kSingleProcess))
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    crypto::InitNSSSafely();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // crypt32.dll is used to decode X509 certificates for Chromoting.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only load this library when the feature is enabled.
300effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::LoadNativeLibrary(base::FilePath(L"crypt32.dll"), NULL);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup initial set of crash dump data for Field Trials in this renderer.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_variations::SetChildProcessLoggingVariationList();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeRenderProcessObserver::~ChromeRenderProcessObserver() {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeRenderProcessObserver::OnControlMessageReceived(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message) {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSetIsIncognitoProcess)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_GetV8HeapStats, OnGetV8HeapStats)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnGetCacheResourceStats)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSetContentSettingRules)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ChromeRenderProcessObserver::WebKitInitialized() {
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  webkit_initialized_ = true;
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // chrome-native: is a scheme used for placeholder navigations that allow
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // UIs to be drawn with platform native widgets instead of HTML.  These pages
3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // should not be accessible, and should also be treated as empty documents
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // that can commit synchronously.  No code should be runnable in these pages,
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // so it should not need to access anything nor should it allow javascript
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // URLs since it should never be visible to the user.
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WebString native_scheme(base::ASCIIToUTF16(chrome::kChromeNativeScheme));
3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(native_scheme);
3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebSecurityPolicy::registerURLSchemeAsEmptyDocument(native_scheme);
3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebSecurityPolicy::registerURLSchemeAsNoAccess(native_scheme);
3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs(
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      native_scheme);
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ChromeRenderProcessObserver::OnRenderProcessShutdown() {
3433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  webkit_initialized_ = false;
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeRenderProcessObserver::OnSetIsIncognitoProcess(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_incognito_process) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_incognito_process_ = is_incognito_process;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeRenderProcessObserver::OnSetContentSettingRules(
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const RendererContentSettingRules& rules) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content_setting_rules_ = rules;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeRenderProcessObserver::OnGetCacheResourceStats() {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebCache::ResourceTypeStats stats;
3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (webkit_initialized_)
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    WebCache::getResourceTypeStats(&stats);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderThread::Get()->Send(new ChromeViewHostMsg_ResourceTypeStats(stats));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeRenderProcessObserver::OnSetFieldTrialGroup(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& field_trial_name,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& group_name) {
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FieldTrial* trial =
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FieldTrialList::CreateFieldTrial(field_trial_name, group_name);
368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // TODO(mef): Remove this check after the investigation of 359406 is complete.
369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CHECK(trial) << field_trial_name << ":" << group_name;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure the trial is marked as "used" by calling group() on it. This is
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // needed to ensure the trial is properly reported in renderer crash reports.
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trial->group();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_variations::SetChildProcessLoggingVariationList();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeRenderProcessObserver::OnGetV8HeapStats() {
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HeapStatisticsCollector::Instance()->InitiateCollection();
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const RendererContentSettingRules*
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeRenderProcessObserver::content_setting_rules() const {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &content_setting_rules_;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
384