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 "chrome/browser/chrome_net_benchmarking_message_filter.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/command_line.h"
10#include "base/macros.h"
11#include "base/memory/scoped_ptr.h"
12#include "chrome/browser/net/predictor.h"
13#include "chrome/browser/profiles/profile.h"
14#include "chrome/common/benchmarking_messages.h"
15#include "chrome/common/chrome_switches.h"
16#include "net/base/net_errors.h"
17#include "net/disk_cache/disk_cache.h"
18#include "net/dns/host_cache.h"
19#include "net/dns/host_resolver.h"
20#include "net/http/http_cache.h"
21#include "net/url_request/url_request_context.h"
22#include "net/url_request/url_request_context_getter.h"
23
24namespace {
25
26void ClearCacheCallback(ChromeNetBenchmarkingMessageFilter* filter,
27                        IPC::Message* reply_msg,
28                        int result) {
29  ChromeViewHostMsg_ClearCache::WriteReplyParams(reply_msg, result);
30  filter->Send(reply_msg);
31}
32
33}  // namespace
34
35ChromeNetBenchmarkingMessageFilter::ChromeNetBenchmarkingMessageFilter(
36    Profile* profile,
37    net::URLRequestContextGetter* request_context)
38    : BrowserMessageFilter(ChromeBenchmarkingMsgStart),
39      profile_(profile),
40      request_context_(request_context) {
41}
42
43ChromeNetBenchmarkingMessageFilter::~ChromeNetBenchmarkingMessageFilter() {
44}
45
46bool ChromeNetBenchmarkingMessageFilter::OnMessageReceived(
47    const IPC::Message& message) {
48  bool handled = true;
49  IPC_BEGIN_MESSAGE_MAP(ChromeNetBenchmarkingMessageFilter, message)
50    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CloseCurrentConnections,
51                        OnCloseCurrentConnections)
52    IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_ClearCache, OnClearCache)
53    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ClearHostResolverCache,
54                        OnClearHostResolverCache)
55    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ClearPredictorCache,
56                        OnClearPredictorCache)
57    IPC_MESSAGE_UNHANDLED(handled = false)
58  IPC_END_MESSAGE_MAP()
59  return handled;
60}
61
62void ChromeNetBenchmarkingMessageFilter::OnClearCache(IPC::Message* reply_msg) {
63  // This function is disabled unless the user has enabled
64  // benchmarking extensions.
65  if (!CheckBenchmarkingEnabled()) {
66    NOTREACHED() << "Received unexpected benchmarking IPC";
67    return;
68  }
69  int rv = -1;
70
71  disk_cache::Backend* backend = request_context_->GetURLRequestContext()->
72      http_transaction_factory()->GetCache()->GetCurrentBackend();
73  if (backend) {
74    net::CompletionCallback callback =
75        base::Bind(&ClearCacheCallback, make_scoped_refptr(this), reply_msg);
76    rv = backend->DoomAllEntries(callback);
77    if (rv == net::ERR_IO_PENDING) {
78      // The callback will send the reply.
79      return;
80    }
81  }
82  ChromeViewHostMsg_ClearCache::WriteReplyParams(reply_msg, rv);
83  Send(reply_msg);
84}
85
86void ChromeNetBenchmarkingMessageFilter::OnClearHostResolverCache(int* result) {
87  // This function is disabled unless the user has enabled
88  // benchmarking extensions.
89  if (!CheckBenchmarkingEnabled()) {
90    NOTREACHED() << "Received unexpected benchmarking IPC";
91    return;
92  }
93  *result = -1;
94  net::HostCache* cache =
95      request_context_->GetURLRequestContext()->host_resolver()->GetHostCache();
96  if (cache) {
97    cache->clear();
98    *result = 0;
99  }
100}
101
102void ChromeNetBenchmarkingMessageFilter::OnCloseCurrentConnections() {
103  // This function is disabled unless the user has enabled
104  // benchmarking extensions.
105  if (!CheckBenchmarkingEnabled()) {
106    NOTREACHED() << "Received unexpected benchmarking IPC";
107    return;
108  }
109  request_context_->GetURLRequestContext()->
110      http_transaction_factory()->GetCache()->CloseAllConnections();
111}
112
113void ChromeNetBenchmarkingMessageFilter::OnSetCacheMode(bool enabled) {
114  // This function is disabled unless the user has enabled
115  // benchmarking extensions.
116  if (!CheckBenchmarkingEnabled()) {
117    NOTREACHED() << "Received unexpected benchmarking IPC";
118    return;
119  }
120  net::HttpCache::Mode mode = enabled ?
121      net::HttpCache::NORMAL : net::HttpCache::DISABLE;
122  net::HttpCache* http_cache = request_context_->GetURLRequestContext()->
123      http_transaction_factory()->GetCache();
124  http_cache->set_mode(mode);
125}
126
127void ChromeNetBenchmarkingMessageFilter::OnClearPredictorCache(int* result) {
128  // This function is disabled unless the user has enabled
129  // benchmarking extensions.
130  if (!CheckBenchmarkingEnabled()) {
131    NOTREACHED() << "Received unexpected benchmarking IPC";
132    return;
133  }
134  chrome_browser_net::Predictor* predictor = profile_->GetNetworkPredictor();
135  if (predictor)
136    predictor->DiscardAllResults();
137  *result = 0;
138}
139
140bool ChromeNetBenchmarkingMessageFilter::CheckBenchmarkingEnabled() const {
141  static bool checked = false;
142  static bool result = false;
143  if (!checked) {
144    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
145    result = command_line.HasSwitch(switches::kEnableNetBenchmarking);
146    checked = true;
147  }
148  return result;
149}
150
151