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.
5 #include "webkit/support/webkit_support.h"
7 #include "base/at_exit.h"
8 #include "base/base64.h"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.h"
12 #include "base/debug/debugger.h"
13 #include "base/file_path.h"
14 #include "base/file_util.h"
15 #include "base/i18n/icu_util.h"
16 #include "base/logging.h"
17 #include "base/memory/ref_counted.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/message_loop.h"
20 #include "base/path_service.h"
21 #include "base/process_util.h"
22 #include "base/scoped_temp_dir.h"
23 #include "base/string_piece.h"
24 #include "base/string_util.h"
25 #include "base/stringprintf.h"
26 #include "base/sys_string_conversions.h"
27 #include "base/time.h"
28 #include "base/utf_string_conversions.h"
29 #include "googleurl/src/url_util.h"
30 #include "grit/webkit_chromium_resources.h"
31 #include "media/base/filter_collection.h"
32 #include "media/base/media_log.h"
33 #include "media/base/message_loop_factory.h"
34 #include "net/base/escape.h"
35 #include "net/base/net_errors.h"
36 #include "net/base/net_util.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h"
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h"
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebStorageNamespace.h"
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
44 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h"
45 #if defined(TOOLKIT_GTK)
46 #include "ui/base/keycodes/keyboard_code_conversion_gtk.h"
48 #include "ui/gl/gl_context.h"
49 #include "ui/gl/gl_implementation.h"
50 #include "ui/gl/gl_surface.h"
51 #include "webkit/appcache/web_application_cache_host_impl.h"
52 #include "webkit/fileapi/isolated_context.h"
53 #include "webkit/glue/user_agent.h"
54 #include "webkit/glue/webkit_constants.h"
55 #include "webkit/glue/webkit_glue.h"
56 #include "webkit/glue/webkitplatformsupport_impl.h"
57 #include "webkit/glue/weburlrequest_extradata_impl.h"
58 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
59 #include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"
60 #if defined(OS_ANDROID)
61 #include "webkit/media/android/webmediaplayer_android.h"
62 #include "webkit/media/android/webmediaplayer_manager_android.h"
64 #include "webkit/media/webmediaplayer_impl.h"
65 #include "webkit/plugins/npapi/plugin_list.h"
66 #include "webkit/plugins/npapi/webplugin_impl.h"
67 #include "webkit/plugins/npapi/webplugin_page_delegate.h"
68 #include "webkit/plugins/webplugininfo.h"
69 #include "webkit/support/platform_support.h"
70 #include "webkit/support/simple_database_system.h"
71 #include "webkit/support/test_webkit_platform_support.h"
72 #include "webkit/support/test_webplugin_page_delegate.h"
73 #include "webkit/tools/test_shell/simple_appcache_system.h"
74 #include "webkit/tools/test_shell/simple_dom_storage_system.h"
75 #include "webkit/tools/test_shell/simple_file_system.h"
76 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
78 #if defined(OS_ANDROID)
79 #include "base/test/test_support_android.h"
80 #include "webkit/support/test_stream_texture_factory_android.h"
83 using WebKit::WebCString
;
84 using WebKit::WebDevToolsAgentClient
;
85 using WebKit::WebFileSystem
;
86 using WebKit::WebFileSystemCallbacks
;
87 using WebKit::WebFrame
;
88 using WebKit::WebMediaPlayerClient
;
89 using WebKit::WebPlugin
;
90 using WebKit::WebPluginParams
;
91 using WebKit::WebString
;
93 using webkit::gpu::WebGraphicsContext3DInProcessImpl
;
94 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl
;
98 // All fatal log messages (e.g. DCHECK failures) imply unit test failures
99 void UnitTestAssertHandler(const std::string
& str
) {
105 if (!::IsDebuggerPresent()) {
106 UINT new_flags
= SEM_FAILCRITICALERRORS
| SEM_NOOPENFILEERRORBOX
107 | SEM_NOGPFAULTERRORBOX
;
109 // Preserve existing error mode, as discussed at
110 // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
111 UINT existing_flags
= SetErrorMode(new_flags
);
112 SetErrorMode(existing_flags
| new_flags
);
116 #if defined(OS_ANDROID)
117 // On Android we expect the log to appear in logcat.
118 base::InitAndroidTestLogging();
120 FilePath log_filename
;
121 PathService::Get(base::DIR_EXE
, &log_filename
);
122 log_filename
= log_filename
.AppendASCII("DumpRenderTree.log");
123 logging::InitLogging(
124 log_filename
.value().c_str(),
125 // Only log to a file. This prevents debugging output from disrupting
126 // whether or not we pass.
127 logging::LOG_ONLY_TO_FILE
,
128 // We might have multiple DumpRenderTree processes going at once.
129 logging::LOCK_LOG_FILE
,
130 logging::DELETE_OLD_LOG_FILE
,
131 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS
);
133 // We want process and thread IDs because we may have multiple processes.
134 const bool kProcessId
= true;
135 const bool kThreadId
= true;
136 const bool kTimestamp
= true;
137 const bool kTickcount
= true;
138 logging::SetLogItems(kProcessId
, kThreadId
, !kTimestamp
, kTickcount
);
139 #endif // else defined(OS_ANDROID)
142 class TestEnvironment
{
144 #if defined(OS_ANDROID)
145 // Android UI message loop goes through Java, so don't use it in tests.
146 typedef MessageLoop MessageLoopType
;
148 typedef MessageLoopForUI MessageLoopType
;
151 TestEnvironment(bool unit_test_mode
,
152 base::AtExitManager
* existing_at_exit_manager
,
153 WebKit::Platform
* shadow_platform_delegate
) {
154 if (unit_test_mode
) {
155 logging::SetLogAssertHandler(UnitTestAssertHandler
);
157 // The existing_at_exit_manager must be not NULL.
158 at_exit_manager_
.reset(existing_at_exit_manager
);
161 main_message_loop_
.reset(new MessageLoopType
);
163 // TestWebKitPlatformSupport must be instantiated after MessageLoopType.
164 webkit_platform_support_
.reset(
165 new TestWebKitPlatformSupport(unit_test_mode
,
166 shadow_platform_delegate
));
168 #if defined(OS_ANDROID)
169 media_player_manager_
.reset(
170 new webkit_media::WebMediaPlayerManagerAndroid());
175 SimpleResourceLoaderBridge::Shutdown();
178 TestWebKitPlatformSupport
* webkit_platform_support() const {
179 return webkit_platform_support_
.get();
182 #if defined(OS_WIN) || defined(OS_MACOSX)
183 void set_theme_engine(WebKit::WebThemeEngine
* engine
) {
184 DCHECK(webkit_platform_support_
!= 0);
185 webkit_platform_support_
->SetThemeEngine(engine
);
188 WebKit::WebThemeEngine
* theme_engine() const {
189 return webkit_platform_support_
->themeEngine();
193 #if defined(OS_ANDROID)
194 // On Android under layout test mode, we mock the current directory
195 // in SetCurrentDirectoryForFileURL() and GetAbsoluteWebStringFromUTF8Path(),
196 // as the directory might not exist on the device because we are using
197 // file-over-http bridge.
198 void set_mock_current_directory(const FilePath
& directory
) {
199 mock_current_directory_
= directory
;
202 FilePath
mock_current_directory() const {
203 return mock_current_directory_
;
206 webkit_media::WebMediaPlayerManagerAndroid
* media_player_manager() {
207 return media_player_manager_
.get();
212 // Data member at_exit_manager_ will take the ownership of the input
213 // AtExitManager and manage its lifecycle.
214 scoped_ptr
<base::AtExitManager
> at_exit_manager_
;
215 scoped_ptr
<MessageLoopType
> main_message_loop_
;
216 scoped_ptr
<TestWebKitPlatformSupport
> webkit_platform_support_
;
218 #if defined(OS_ANDROID)
219 FilePath mock_current_directory_
;
220 scoped_ptr
<webkit_media::WebMediaPlayerManagerAndroid
> media_player_manager_
;
224 class WebPluginImplWithPageDelegate
225 : public webkit_support::TestWebPluginPageDelegate
,
226 public base::SupportsWeakPtr
<WebPluginImplWithPageDelegate
>,
227 public webkit::npapi::WebPluginImpl
{
229 WebPluginImplWithPageDelegate(WebFrame
* frame
,
230 const WebPluginParams
& params
,
231 const FilePath
& path
)
232 : webkit_support::TestWebPluginPageDelegate(),
233 webkit::npapi::WebPluginImpl(frame
, params
, path
, AsWeakPtr()) {}
234 virtual ~WebPluginImplWithPageDelegate() {}
236 DISALLOW_COPY_AND_ASSIGN(WebPluginImplWithPageDelegate
);
239 FilePath
GetWebKitRootDirFilePath() {
241 PathService::Get(base::DIR_SOURCE_ROOT
, &basePath
);
242 if (file_util::PathExists(
243 basePath
.Append(FILE_PATH_LITERAL("third_party/WebKit")))) {
244 // We're in a WebKit-in-chrome checkout.
245 return basePath
.Append(FILE_PATH_LITERAL("third_party/WebKit"));
246 } else if (file_util::PathExists(
247 basePath
.Append(FILE_PATH_LITERAL("chromium")))) {
248 // We're in a WebKit-only checkout on Windows.
249 return basePath
.Append(FILE_PATH_LITERAL("../.."));
250 } else if (file_util::PathExists(
251 basePath
.Append(FILE_PATH_LITERAL("webkit/support")))) {
252 // We're in a WebKit-only/xcodebuild checkout on Mac
253 return basePath
.Append(FILE_PATH_LITERAL("../../.."));
255 // We're in a WebKit-only, make-build, so the DIR_SOURCE_ROOT is already the
256 // WebKit root. That, or we have no idea where we are.
260 class WebKitClientMessageLoopImpl
261 : public WebDevToolsAgentClient::WebKitClientMessageLoop
{
263 WebKitClientMessageLoopImpl() : message_loop_(MessageLoop::current()) {}
264 virtual ~WebKitClientMessageLoopImpl() {
265 message_loop_
= NULL
;
268 MessageLoop::ScopedNestableTaskAllower
allow(message_loop_
);
269 message_loop_
->Run();
271 virtual void quitNow() {
272 message_loop_
->QuitNow();
275 MessageLoop
* message_loop_
;
278 webkit_support::GraphicsContext3DImplementation
279 g_graphics_context_3d_implementation
=
280 webkit_support::IN_PROCESS_COMMAND_BUFFER
;
282 TestEnvironment
* test_environment
;
284 void SetUpTestEnvironmentImpl(bool unit_test_mode
,
285 WebKit::Platform
* shadow_platform_delegate
) {
286 base::EnableInProcessStackDumping();
287 base::EnableTerminationOnHeapCorruption();
289 // Initialize the singleton CommandLine with fixed values. Some code refer to
290 // CommandLine::ForCurrentProcess(). We don't use the actual command-line
291 // arguments of DRT to avoid unexpected behavior change.
293 // webkit/glue/plugin/plugin_list_posix.cc checks --debug-plugin-loading.
294 // webkit/glue/plugin/plugin_list_win.cc checks --old-wmp.
295 // If DRT needs these flags, specify them in the following kFixedArguments.
296 const char* kFixedArguments
[] = {"DumpRenderTree"};
297 CommandLine::Init(arraysize(kFixedArguments
), kFixedArguments
);
299 // Explicitly initialize the GURL library before spawning any threads.
300 // Otherwise crash may happend when different threads try to create a GURL
302 url_util::Initialize();
303 base::AtExitManager
* at_exit_manager
= NULL
;
304 // In Android DumpRenderTree, AtExitManager is created in
305 // testing/android/native_test_wrapper.cc before main() is called.
306 #if !defined(OS_ANDROID)
307 // Some initialization code may use a AtExitManager before initializing
308 // TestEnvironment, so we create a AtExitManager early and pass its ownership
309 // to TestEnvironment.
311 at_exit_manager
= new base::AtExitManager
;
313 webkit_support::BeforeInitialize(unit_test_mode
);
314 test_environment
= new TestEnvironment(unit_test_mode
, at_exit_manager
,
315 shadow_platform_delegate
);
316 webkit_support::AfterInitialize(unit_test_mode
);
317 if (!unit_test_mode
) {
318 // Load ICU data tables. This has to run after TestEnvironment is created
319 // because on Linux, we need base::AtExitManager.
320 icu_util::Initialize();
322 webkit_glue::SetUserAgent(webkit_glue::BuildUserAgentFromProduct(
323 "DumpRenderTree/0.0.0.0"), false);
328 namespace webkit_support
{
330 void SetUpTestEnvironment() {
331 SetUpTestEnvironment(NULL
);
334 void SetUpTestEnvironmentForUnitTests() {
335 SetUpTestEnvironmentForUnitTests(NULL
);
338 void SetUpTestEnvironment(WebKit::Platform
* shadow_platform_delegate
) {
339 SetUpTestEnvironmentImpl(false, shadow_platform_delegate
);
342 void SetUpTestEnvironmentForUnitTests(
343 WebKit::Platform
* shadow_platform_delegate
) {
344 SetUpTestEnvironmentImpl(true, shadow_platform_delegate
);
347 void TearDownTestEnvironment() {
348 // Flush any remaining messages before we kill ourselves.
349 // http://code.google.com/p/chromium/issues/detail?id=9500
350 MessageLoop::current()->RunAllPending();
353 if (RunningOnValgrind())
354 WebKit::WebCache::clear();
356 delete test_environment
;
357 test_environment
= NULL
;
359 logging::CloseLogFile();
362 WebKit::WebKitPlatformSupport
* GetWebKitPlatformSupport() {
363 DCHECK(test_environment
);
364 return test_environment
->webkit_platform_support();
367 WebPlugin
* CreateWebPlugin(WebFrame
* frame
,
368 const WebPluginParams
& params
) {
369 const bool kAllowWildcard
= true;
370 std::vector
<webkit::WebPluginInfo
> plugins
;
371 std::vector
<std::string
> mime_types
;
372 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray(
373 params
.url
, params
.mimeType
.utf8(), kAllowWildcard
,
374 NULL
, &plugins
, &mime_types
);
378 WebPluginParams new_params
= params
;
379 new_params
.mimeType
= WebString::fromUTF8(mime_types
.front());
380 return new WebPluginImplWithPageDelegate(
381 frame
, new_params
, plugins
.front().path
);
384 WebKit::WebMediaPlayer
* CreateMediaPlayer(
386 WebMediaPlayerClient
* client
,
387 webkit_media::MediaStreamClient
* media_stream_client
) {
388 #if defined(OS_ANDROID)
389 return new webkit_media::WebMediaPlayerAndroid(
392 GetWebKitPlatformSupport()->cookieJar(),
393 test_environment
->media_player_manager(),
394 new webkit_support::TestStreamTextureFactory());
396 scoped_ptr
<media::MessageLoopFactory
> message_loop_factory(
397 new media::MessageLoopFactory());
399 scoped_ptr
<media::FilterCollection
> collection(
400 new media::FilterCollection());
402 return new webkit_media::WebMediaPlayerImpl(
405 base::WeakPtr
<webkit_media::WebMediaPlayerDelegate
>(),
406 collection
.release(),
409 message_loop_factory
.release(),
411 new media::MediaLog());
415 WebKit::WebMediaPlayer
* CreateMediaPlayer(
417 WebMediaPlayerClient
* client
) {
418 return CreateMediaPlayer(frame
, client
, NULL
);
421 #if defined(OS_ANDROID)
422 void ReleaseMediaResources() {
423 test_environment
->media_player_manager()->ReleaseMediaResources();
427 WebKit::WebApplicationCacheHost
* CreateApplicationCacheHost(
428 WebFrame
*, WebKit::WebApplicationCacheHostClient
* client
) {
429 return SimpleAppCacheSystem::CreateApplicationCacheHost(client
);
432 WebKit::WebStorageNamespace
* CreateSessionStorageNamespace(unsigned quota
) {
433 return SimpleDomStorageSystem::instance().CreateSessionStorageNamespace();
436 WebKit::WebString
GetWebKitRootDir() {
437 FilePath path
= GetWebKitRootDirFilePath();
438 std::string path_ascii
= path
.MaybeAsASCII();
439 CHECK(!path_ascii
.empty());
440 return WebKit::WebString::fromUTF8(path_ascii
.c_str());
443 void SetUpGLBindings(GLBindingPreferences bindingPref
) {
444 switch (bindingPref
) {
445 case GL_BINDING_DEFAULT
:
446 gfx::GLSurface::InitializeOneOff();
448 case GL_BINDING_SOFTWARE_RENDERER
:
449 gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL
);
456 void SetGraphicsContext3DImplementation(GraphicsContext3DImplementation impl
) {
457 g_graphics_context_3d_implementation
= impl
;
460 GraphicsContext3DImplementation
GetGraphicsContext3DImplementation() {
461 return g_graphics_context_3d_implementation
;
464 WebKit::WebGraphicsContext3D
* CreateGraphicsContext3D(
465 const WebKit::WebGraphicsContext3D::Attributes
& attributes
,
466 WebKit::WebView
* web_view
) {
467 switch (webkit_support::GetGraphicsContext3DImplementation()) {
468 case webkit_support::IN_PROCESS
:
469 return WebGraphicsContext3DInProcessImpl::CreateForWebView(
470 attributes
, true /* direct */);
471 case webkit_support::IN_PROCESS_COMMAND_BUFFER
: {
472 scoped_ptr
<WebGraphicsContext3DInProcessCommandBufferImpl
> context(
473 new WebGraphicsContext3DInProcessCommandBufferImpl());
474 if (!context
->Initialize(attributes
, NULL
))
476 return context
.release();
483 void RegisterMockedURL(const WebKit::WebURL
& url
,
484 const WebKit::WebURLResponse
& response
,
485 const WebKit::WebString
& file_path
) {
486 test_environment
->webkit_platform_support()->url_loader_factory()->
487 RegisterURL(url
, response
, file_path
);
490 void RegisterMockedErrorURL(const WebKit::WebURL
& url
,
491 const WebKit::WebURLResponse
& response
,
492 const WebKit::WebURLError
& error
) {
493 test_environment
->webkit_platform_support()->url_loader_factory()->
494 RegisterErrorURL(url
, response
, error
);
497 void UnregisterMockedURL(const WebKit::WebURL
& url
) {
498 test_environment
->webkit_platform_support()->url_loader_factory()->
502 void UnregisterAllMockedURLs() {
503 test_environment
->webkit_platform_support()->url_loader_factory()->
507 void ServeAsynchronousMockedRequests() {
508 test_environment
->webkit_platform_support()->url_loader_factory()->
509 ServeAsynchronousRequests();
512 WebKit::WebURLRequest
GetLastHandledAsynchronousMockedRequest() {
513 return test_environment
->webkit_platform_support()->url_loader_factory()->
514 GetLastHandledAsynchronousRequest();
517 // Wrapper for debug_util
518 bool BeingDebugged() {
519 return base::debug::BeingDebugged();
522 // Wrappers for MessageLoop
524 void RunMessageLoop() {
525 MessageLoop::current()->Run();
528 void QuitMessageLoop() {
529 MessageLoop::current()->Quit();
532 void QuitMessageLoopNow() {
533 MessageLoop::current()->QuitNow();
536 void RunAllPendingMessages() {
537 MessageLoop::current()->RunAllPending();
540 bool MessageLoopNestableTasksAllowed() {
541 return MessageLoop::current()->NestableTasksAllowed();
544 void MessageLoopSetNestableTasksAllowed(bool allowed
) {
545 MessageLoop::current()->SetNestableTasksAllowed(allowed
);
548 void DispatchMessageLoop() {
549 MessageLoop
* current
= MessageLoop::current();
550 MessageLoop::ScopedNestableTaskAllower
allow(current
);
551 current
->RunAllPending();
554 WebDevToolsAgentClient::WebKitClientMessageLoop
* CreateDevToolsMessageLoop() {
555 return new WebKitClientMessageLoopImpl();
558 void PostDelayedTask(void (*func
)(void*), void* context
, int64 delay_ms
) {
559 MessageLoop::current()->PostDelayedTask(
561 base::Bind(func
, context
),
562 base::TimeDelta::FromMilliseconds(delay_ms
));
565 void PostDelayedTask(TaskAdaptor
* task
, int64 delay_ms
) {
566 MessageLoop::current()->PostDelayedTask(
568 base::Bind(&TaskAdaptor::Run
, base::Owned(task
)),
569 base::TimeDelta::FromMilliseconds(delay_ms
));
572 // Wrappers for FilePath and file_util
574 WebString
GetAbsoluteWebStringFromUTF8Path(const std::string
& utf8_path
) {
576 FilePath
path(UTF8ToWide(utf8_path
));
577 file_util::AbsolutePath(&path
);
578 return WebString(path
.value());
580 FilePath
path(base::SysWideToNativeMB(base::SysUTF8ToWide(utf8_path
)));
581 #if defined(OS_ANDROID)
582 if (WebKit::layoutTestMode()) {
583 // See comment of TestEnvironment::set_mock_current_directory().
584 if (!path
.IsAbsolute()) {
585 // Not using FilePath::Append() because it can't handle '..' in path.
586 DCHECK(test_environment
);
587 GURL base_url
= net::FilePathToFileURL(
588 test_environment
->mock_current_directory()
589 .Append(FILE_PATH_LITERAL("foo")));
590 net::FileURLToFilePath(base_url
.Resolve(path
.value()), &path
);
593 file_util::AbsolutePath(&path
);
596 file_util::AbsolutePath(&path
);
597 #endif // else defined(OS_ANDROID)
598 return WideToUTF16(base::SysNativeMBToWide(path
.value()));
599 #endif // else defined(OS_WIN)
602 WebURL
CreateURLForPathOrURL(const std::string
& path_or_url_in_nativemb
) {
604 std::wstring wide_path_or_url
605 = base::SysNativeMBToWide(path_or_url_in_nativemb
);
606 std::string path_or_url_in_utf8
= WideToUTF8(wide_path_or_url
);
608 GURL
url(path_or_url_in_utf8
);
609 if (url
.is_valid() && url
.has_scheme())
612 return net::FilePathToFileURL(FilePath(wide_path_or_url
));
614 return net::FilePathToFileURL(FilePath(path_or_url_in_nativemb
));
618 WebURL
RewriteLayoutTestsURL(const std::string
& utf8_url
) {
619 const char kPrefix
[] = "file:///tmp/LayoutTests/";
620 const int kPrefixLen
= arraysize(kPrefix
) - 1;
622 if (utf8_url
.compare(0, kPrefixLen
, kPrefix
, kPrefixLen
))
623 return WebURL(GURL(utf8_url
));
625 FilePath replacePath
=
626 GetWebKitRootDirFilePath().Append(FILE_PATH_LITERAL("LayoutTests/"));
628 // On Android, the file is actually accessed through file-over-http. Disable
629 // the following CHECK because the file is unlikely to exist on the device.
630 #if !defined(OS_ANDROID)
631 CHECK(file_util::PathExists(replacePath
)) << replacePath
.value() <<
632 " (re-written from " << utf8_url
<< ") does not exit";
636 std::string utf8_path
= WideToUTF8(replacePath
.value());
638 std::string utf8_path
639 = WideToUTF8(base::SysNativeMBToWide(replacePath
.value()));
641 std::string newUrl
= std::string("file://") + utf8_path
642 + utf8_url
.substr(kPrefixLen
);
643 return WebURL(GURL(newUrl
));
646 bool SetCurrentDirectoryForFileURL(const WebKit::WebURL
& fileUrl
) {
648 if (!net::FileURLToFilePath(fileUrl
, &local_path
))
650 #if defined(OS_ANDROID)
651 if (WebKit::layoutTestMode()) {
652 // See comment of TestEnvironment::set_mock_current_directory().
653 DCHECK(test_environment
);
654 FilePath directory
= local_path
.DirName();
655 test_environment
->set_mock_current_directory(directory
);
656 // Still try to actually change the directory, but ignore any error.
657 // For a few tests that need to access resources directly as files
658 // (e.g. blob tests) we still push the resources and need to chdir there.
659 file_util::SetCurrentDirectory(directory
);
663 return file_util::SetCurrentDirectory(local_path
.DirName());
666 WebURL
LocalFileToDataURL(const WebURL
& fileUrl
) {
668 if (!net::FileURLToFilePath(fileUrl
, &local_path
))
671 std::string contents
;
672 if (!file_util::ReadFileToString(local_path
, &contents
))
675 std::string contents_base64
;
676 if (!base::Base64Encode(contents
, &contents_base64
))
679 const char kDataUrlPrefix
[] = "data:text/css;charset=utf-8;base64,";
680 return WebURL(GURL(kDataUrlPrefix
+ contents_base64
));
683 // A wrapper object for exporting ScopedTempDir to be used
684 // by webkit layout tests.
685 class ScopedTempDirectoryInternal
: public ScopedTempDirectory
{
687 virtual bool CreateUniqueTempDir() {
688 return tempDirectory_
.CreateUniqueTempDir();
691 virtual std::string
path() const {
692 return tempDirectory_
.path().MaybeAsASCII();
696 ScopedTempDir tempDirectory_
;
699 ScopedTempDirectory
* CreateScopedTempDirectory() {
700 return new ScopedTempDirectoryInternal();
703 int64
GetCurrentTimeInMillisecond() {
704 return base::TimeTicks::Now().ToInternalValue()
705 / base::Time::kMicrosecondsPerMillisecond
;
708 std::string
EscapePath(const std::string
& path
) {
709 return net::EscapePath(path
);
712 std::string
MakeURLErrorDescription(const WebKit::WebURLError
& error
) {
713 std::string domain
= error
.domain
.utf8();
714 int code
= error
.reason
;
716 if (domain
== net::kErrorDomain
) {
717 domain
= "NSURLErrorDomain";
718 switch (error
.reason
) {
719 case net::ERR_ABORTED
:
720 code
= -999; // NSURLErrorCancelled
722 case net::ERR_UNSAFE_PORT
:
723 // Our unsafe port checking happens at the network stack level, but we
724 // make this translation here to match the behavior of stock WebKit.
725 domain
= "WebKitErrorDomain";
728 case net::ERR_ADDRESS_INVALID
:
729 case net::ERR_ADDRESS_UNREACHABLE
:
730 case net::ERR_NETWORK_ACCESS_DENIED
:
731 code
= -1004; // NSURLErrorCannotConnectToHost
735 DLOG(WARNING
) << "Unknown error domain";
738 return base::StringPrintf("<NSError domain %s, code %d, failing URL \"%s\">",
739 domain
.c_str(), code
, error
.unreachableURL
.spec().data());
742 WebKit::WebURLError
CreateCancelledError(const WebKit::WebURLRequest
& request
) {
743 WebKit::WebURLError error
;
744 error
.domain
= WebKit::WebString::fromUTF8(net::kErrorDomain
);
745 error
.reason
= net::ERR_ABORTED
;
746 error
.unreachableURL
= request
.url();
750 WebKit::WebURLRequest::ExtraData
* CreateWebURLRequestExtraData(
751 WebKit::WebReferrerPolicy referrer_policy
) {
752 return new webkit_glue::WebURLRequestExtraDataImpl(referrer_policy
,
753 WebKit::WebString());
756 // Bridge for SimpleDatabaseSystem
758 void SetDatabaseQuota(int quota
) {
759 SimpleDatabaseSystem::GetInstance()->SetDatabaseQuota(quota
);
762 void ClearAllDatabases() {
763 SimpleDatabaseSystem::GetInstance()->ClearAllDatabases();
766 // Bridge for SimpleResourceLoaderBridge
768 void SetAcceptAllCookies(bool accept
) {
769 SimpleResourceLoaderBridge::SetAcceptAllCookies(accept
);
773 #if defined(OS_WIN) || defined(OS_MACOSX)
775 void SetThemeEngine(WebKit::WebThemeEngine
* engine
) {
776 DCHECK(test_environment
);
777 test_environment
->set_theme_engine(engine
);
780 WebKit::WebThemeEngine
* GetThemeEngine() {
781 DCHECK(test_environment
);
782 return test_environment
->theme_engine();
788 WebURL
GetDevToolsPathAsURL() {
790 if (!PathService::Get(base::DIR_EXE
, &dirExe
)) {
794 FilePath devToolsPath
= dirExe
.AppendASCII(
795 "resources/inspector/devtools.html");
796 return net::FilePathToFileURL(devToolsPath
);
800 void OpenFileSystem(WebFrame
* frame
, WebFileSystem::Type type
,
801 long long size
, bool create
, WebFileSystemCallbacks
* callbacks
) {
802 SimpleFileSystem
* fileSystem
= static_cast<SimpleFileSystem
*>(
803 test_environment
->webkit_platform_support()->fileSystem());
804 fileSystem
->OpenFileSystem(frame
, type
, size
, create
, callbacks
);
807 WebKit::WebString
RegisterIsolatedFileSystem(
808 const WebKit::WebVector
<WebKit::WebString
>& filenames
) {
809 fileapi::IsolatedContext::FileInfoSet files
;
810 for (size_t i
= 0; i
< filenames
.size(); ++i
) {
811 FilePath path
= webkit_glue::WebStringToFilePath(filenames
[i
]);
812 files
.AddPath(path
, NULL
);
814 std::string filesystemId
=
815 fileapi::IsolatedContext::GetInstance()->RegisterDraggedFileSystem(files
);
816 return UTF8ToUTF16(filesystemId
);
820 #if defined(TOOLKIT_GTK)
821 int NativeKeyCodeForWindowsKeyCode(int keycode
, bool shift
) {
822 ui::KeyboardCode code
= static_cast<ui::KeyboardCode
>(keycode
);
823 return ui::GdkNativeKeyCodeForWindowsKeyCode(code
, shift
);
828 double GetForegroundTabTimerInterval() {
829 return webkit_glue::kForegroundTabTimerInterval
;
833 void EnableWebCoreLogChannels(const std::string
& channels
) {
834 webkit_glue::EnableWebCoreLogChannels(channels
);
837 void SetGamepadData(const WebKit::WebGamepads
& pads
) {
838 test_environment
->webkit_platform_support()->setGamepadData(pads
);
841 } // namespace webkit_support