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/test/test_webkit_platform_support.h"
6
7#include "base/command_line.h"
8#include "base/files/file_path.h"
9#include "base/files/file_util.h"
10#include "base/files/scoped_temp_dir.h"
11#include "base/metrics/stats_counters.h"
12#include "base/path_service.h"
13#include "base/strings/utf_string_conversions.h"
14#include "content/public/common/content_switches.h"
15#include "content/test/mock_webclipboard_impl.h"
16#include "content/test/web_gesture_curve_mock.h"
17#include "content/test/web_layer_tree_view_impl_for_testing.h"
18#include "content/test/weburl_loader_mock_factory.h"
19#include "media/base/media.h"
20#include "net/cookies/cookie_monster.h"
21#include "net/test/spawned_test_server/spawned_test_server.h"
22#include "storage/browser/database/vfs_backend.h"
23#include "third_party/WebKit/public/platform/WebData.h"
24#include "third_party/WebKit/public/platform/WebFileSystem.h"
25#include "third_party/WebKit/public/platform/WebStorageArea.h"
26#include "third_party/WebKit/public/platform/WebStorageNamespace.h"
27#include "third_party/WebKit/public/platform/WebString.h"
28#include "third_party/WebKit/public/platform/WebURL.h"
29#include "third_party/WebKit/public/web/WebDatabase.h"
30#include "third_party/WebKit/public/web/WebKit.h"
31#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
32#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
33#include "third_party/WebKit/public/web/WebStorageEventDispatcher.h"
34#include "v8/include/v8.h"
35
36#if defined(OS_MACOSX)
37#include "base/mac/mac_util.h"
38#include "base/mac/scoped_nsautorelease_pool.h"
39#endif
40
41namespace content {
42
43TestWebKitPlatformSupport::TestWebKitPlatformSupport() {
44#if defined(OS_MACOSX)
45  base::mac::ScopedNSAutoreleasePool autorelease_pool;
46#endif
47
48  url_loader_factory_.reset(new WebURLLoaderMockFactory());
49  mock_clipboard_.reset(new MockWebClipboardImpl());
50
51  // Create an anonymous stats table since we don't need to share between
52  // processes.
53  stats_table_.reset(
54      new base::StatsTable(base::StatsTable::TableIdentifier(), 20, 200));
55  base::StatsTable::set_current(stats_table_.get());
56
57  blink::initialize(this);
58  blink::mainThreadIsolate()->SetCounterFunction(
59      base::StatsTable::FindLocation);
60  blink::setLayoutTestMode(true);
61  blink::WebSecurityPolicy::registerURLSchemeAsLocal(
62      blink::WebString::fromUTF8("test-shell-resource"));
63  blink::WebSecurityPolicy::registerURLSchemeAsNoAccess(
64      blink::WebString::fromUTF8("test-shell-resource"));
65  blink::WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(
66      blink::WebString::fromUTF8("test-shell-resource"));
67  blink::WebSecurityPolicy::registerURLSchemeAsEmptyDocument(
68      blink::WebString::fromUTF8("test-shell-resource"));
69  blink::WebRuntimeFeatures::enableApplicationCache(true);
70  blink::WebRuntimeFeatures::enableDatabase(true);
71  blink::WebRuntimeFeatures::enableNotifications(true);
72  blink::WebRuntimeFeatures::enableTouch(true);
73
74  // Load libraries for media and enable the media player.
75  bool enable_media = false;
76  base::FilePath module_path;
77  if (PathService::Get(base::DIR_MODULE, &module_path)) {
78#if defined(OS_MACOSX)
79    if (base::mac::AmIBundled())
80      module_path = module_path.DirName().DirName().DirName();
81#endif
82    if (media::InitializeMediaLibrary(module_path))
83      enable_media = true;
84  }
85  blink::WebRuntimeFeatures::enableMediaPlayer(enable_media);
86  LOG_IF(WARNING, !enable_media) << "Failed to initialize the media library.\n";
87
88  file_utilities_.set_sandbox_enabled(false);
89
90  if (!file_system_root_.CreateUniqueTempDir()) {
91    LOG(WARNING) << "Failed to create a temp dir for the filesystem."
92                    "FileSystem feature will be disabled.";
93    DCHECK(file_system_root_.path().empty());
94  }
95
96#if defined(OS_WIN)
97  // Ensure we pick up the default theme engine.
98  SetThemeEngine(NULL);
99#endif
100
101  CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableFileCookies);
102
103  // Test shell always exposes the GC.
104  std::string flags("--expose-gc");
105  v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size()));
106}
107
108TestWebKitPlatformSupport::~TestWebKitPlatformSupport() {
109  url_loader_factory_.reset();
110  mock_clipboard_.reset();
111  blink::shutdown();
112  base::StatsTable::set_current(NULL);
113  stats_table_.reset();
114}
115
116blink::WebBlobRegistry* TestWebKitPlatformSupport::blobRegistry() {
117  return &blob_registry_;
118}
119
120blink::WebClipboard* TestWebKitPlatformSupport::clipboard() {
121  // Mock out clipboard calls so that tests don't mess
122  // with each other's copies/pastes when running in parallel.
123  return mock_clipboard_.get();
124}
125
126blink::WebFileUtilities* TestWebKitPlatformSupport::fileUtilities() {
127  return &file_utilities_;
128}
129
130blink::WebIDBFactory* TestWebKitPlatformSupport::idbFactory() {
131  NOTREACHED() <<
132      "IndexedDB cannot be tested with in-process harnesses.";
133  return NULL;
134}
135
136blink::WebMimeRegistry* TestWebKitPlatformSupport::mimeRegistry() {
137  return &mime_registry_;
138}
139
140blink::WebURLLoader* TestWebKitPlatformSupport::createURLLoader() {
141  return url_loader_factory_->CreateURLLoader(
142      BlinkPlatformImpl::createURLLoader());
143}
144
145blink::WebString TestWebKitPlatformSupport::userAgent() {
146  return blink::WebString::fromUTF8("DumpRenderTree/0.0.0.0");
147}
148
149blink::WebData TestWebKitPlatformSupport::loadResource(const char* name) {
150  if (!strcmp(name, "deleteButton")) {
151    // Create a red 30x30 square.
152    const char red_square[] =
153        "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52"
154        "\x00\x00\x00\x1e\x00\x00\x00\x1e\x04\x03\x00\x00\x00\xc9\x1e\xb3"
155        "\x91\x00\x00\x00\x30\x50\x4c\x54\x45\x00\x00\x00\x80\x00\x00\x00"
156        "\x80\x00\x80\x80\x00\x00\x00\x80\x80\x00\x80\x00\x80\x80\x80\x80"
157        "\x80\xc0\xc0\xc0\xff\x00\x00\x00\xff\x00\xff\xff\x00\x00\x00\xff"
158        "\xff\x00\xff\x00\xff\xff\xff\xff\xff\x7b\x1f\xb1\xc4\x00\x00\x00"
159        "\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a"
160        "\x9c\x18\x00\x00\x00\x17\x49\x44\x41\x54\x78\x01\x63\x98\x89\x0a"
161        "\x18\x50\xb9\x33\x47\xf9\xa8\x01\x32\xd4\xc2\x03\x00\x33\x84\x0d"
162        "\x02\x3a\x91\xeb\xa5\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60"
163        "\x82";
164    return blink::WebData(red_square, arraysize(red_square));
165  }
166  return BlinkPlatformImpl::loadResource(name);
167}
168
169blink::WebString TestWebKitPlatformSupport::queryLocalizedString(
170    blink::WebLocalizedString::Name name) {
171  // Returns placeholder strings to check if they are correctly localized.
172  switch (name) {
173    case blink::WebLocalizedString::OtherDateLabel:
174      return base::ASCIIToUTF16("<<OtherDateLabel>>");
175    case blink::WebLocalizedString::OtherMonthLabel:
176      return base::ASCIIToUTF16("<<OtherMonthLabel>>");
177    case blink::WebLocalizedString::OtherTimeLabel:
178      return base::ASCIIToUTF16("<<OtherTimeLabel>>");
179    case blink::WebLocalizedString::OtherWeekLabel:
180      return base::ASCIIToUTF16("<<OtherWeekLabel>>");
181    case blink::WebLocalizedString::CalendarClear:
182      return base::ASCIIToUTF16("<<CalendarClear>>");
183    case blink::WebLocalizedString::CalendarToday:
184      return base::ASCIIToUTF16("<<CalendarToday>>");
185    case blink::WebLocalizedString::ThisMonthButtonLabel:
186      return base::ASCIIToUTF16("<<ThisMonthLabel>>");
187    case blink::WebLocalizedString::ThisWeekButtonLabel:
188      return base::ASCIIToUTF16("<<ThisWeekLabel>>");
189    case blink::WebLocalizedString::WeekFormatTemplate:
190      return base::ASCIIToUTF16("Week $2, $1");
191    default:
192      return blink::WebString();
193  }
194}
195
196blink::WebString TestWebKitPlatformSupport::queryLocalizedString(
197    blink::WebLocalizedString::Name name,
198    const blink::WebString& value) {
199  if (name == blink::WebLocalizedString::ValidationRangeUnderflow)
200    return base::ASCIIToUTF16("range underflow");
201  if (name == blink::WebLocalizedString::ValidationRangeOverflow)
202    return base::ASCIIToUTF16("range overflow");
203  if (name == blink::WebLocalizedString::SelectMenuListText)
204    return base::ASCIIToUTF16("$1 selected");
205  return BlinkPlatformImpl::queryLocalizedString(name, value);
206}
207
208blink::WebString TestWebKitPlatformSupport::queryLocalizedString(
209    blink::WebLocalizedString::Name name,
210    const blink::WebString& value1,
211    const blink::WebString& value2) {
212  if (name == blink::WebLocalizedString::ValidationTooLong)
213    return base::ASCIIToUTF16("too long");
214  if (name == blink::WebLocalizedString::ValidationStepMismatch)
215    return base::ASCIIToUTF16("step mismatch");
216  return BlinkPlatformImpl::queryLocalizedString(name, value1, value2);
217}
218
219blink::WebString TestWebKitPlatformSupport::defaultLocale() {
220  return base::ASCIIToUTF16("en-US");
221}
222
223#if defined(OS_WIN) || defined(OS_MACOSX)
224void TestWebKitPlatformSupport::SetThemeEngine(blink::WebThemeEngine* engine) {
225  active_theme_engine_ = engine ? engine : BlinkPlatformImpl::themeEngine();
226}
227
228blink::WebThemeEngine* TestWebKitPlatformSupport::themeEngine() {
229  return active_theme_engine_;
230}
231#endif
232
233blink::WebCompositorSupport* TestWebKitPlatformSupport::compositorSupport() {
234  return &compositor_support_;
235}
236
237blink::WebGestureCurve* TestWebKitPlatformSupport::createFlingAnimationCurve(
238    blink::WebGestureDevice device_source,
239    const blink::WebFloatPoint& velocity,
240    const blink::WebSize& cumulative_scroll) {
241  // Caller will retain and release.
242  return new WebGestureCurveMock(velocity, cumulative_scroll);
243}
244
245blink::WebUnitTestSupport* TestWebKitPlatformSupport::unitTestSupport() {
246  return this;
247}
248
249void TestWebKitPlatformSupport::registerMockedURL(
250    const blink::WebURL& url,
251    const blink::WebURLResponse& response,
252    const blink::WebString& file_path) {
253  url_loader_factory_->RegisterURL(url, response, file_path);
254}
255
256void TestWebKitPlatformSupport::registerMockedErrorURL(
257    const blink::WebURL& url,
258    const blink::WebURLResponse& response,
259    const blink::WebURLError& error) {
260  url_loader_factory_->RegisterErrorURL(url, response, error);
261}
262
263void TestWebKitPlatformSupport::unregisterMockedURL(const blink::WebURL& url) {
264  url_loader_factory_->UnregisterURL(url);
265}
266
267void TestWebKitPlatformSupport::unregisterAllMockedURLs() {
268  url_loader_factory_->UnregisterAllURLs();
269}
270
271void TestWebKitPlatformSupport::serveAsynchronousMockedRequests() {
272  url_loader_factory_->ServeAsynchronousRequests();
273}
274
275blink::WebString TestWebKitPlatformSupport::webKitRootDir() {
276  base::FilePath path;
277  PathService::Get(base::DIR_SOURCE_ROOT, &path);
278  path = path.Append(FILE_PATH_LITERAL("third_party/WebKit"));
279  path = base::MakeAbsoluteFilePath(path);
280  CHECK(!path.empty());
281  std::string path_ascii = path.MaybeAsASCII();
282  CHECK(!path_ascii.empty());
283  return blink::WebString::fromUTF8(path_ascii.c_str());
284}
285
286blink::WebLayerTreeView*
287TestWebKitPlatformSupport::createLayerTreeViewForTesting() {
288  scoped_ptr<WebLayerTreeViewImplForTesting> view(
289      new WebLayerTreeViewImplForTesting());
290
291  view->Initialize();
292  return view.release();
293}
294
295blink::WebData TestWebKitPlatformSupport::readFromFile(
296    const blink::WebString& path) {
297  base::FilePath file_path = base::FilePath::FromUTF16Unsafe(path);
298
299  std::string buffer;
300  base::ReadFileToString(file_path, &buffer);
301
302  return blink::WebData(buffer.data(), buffer.size());
303}
304
305}  // namespace content
306