summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.xcodeproj/project.pbxproj4
-rw-r--r--base/base_lib.scons2
-rw-r--r--base/event_recorder.cc4
-rw-r--r--base/event_recorder.h8
-rw-r--r--base/event_recorder_stubs.cc28
-rw-r--r--webkit/tools/test_shell/SConscript2
-rw-r--r--webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj22
-rw-r--r--webkit/tools/test_shell/mac/main.mm348
-rw-r--r--webkit/tools/test_shell/test_shell.vcproj8
-rw-r--r--webkit/tools/test_shell/test_shell_mac.mm234
-rw-r--r--webkit/tools/test_shell/test_shell_main.cc151
-rw-r--r--webkit/tools/test_shell/test_shell_platform_delegate.h58
-rw-r--r--webkit/tools/test_shell/test_shell_platform_delegate_gtk.cc44
-rw-r--r--webkit/tools/test_shell/test_shell_platform_delegate_mac.mm286
-rw-r--r--webkit/tools/test_shell/test_shell_platform_delegate_win.cc110
-rw-r--r--webkit/tools/test_shell/test_shell_tests.vcproj8
-rw-r--r--webkit/tools/test_shell/test_shell_win.cc10
17 files changed, 611 insertions, 716 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj
index e404033..e5ef83a 100644
--- a/base/base.xcodeproj/project.pbxproj
+++ b/base/base.xcodeproj/project.pbxproj
@@ -155,6 +155,7 @@
A5A0270B0E4A630D00498DA9 /* file_util_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5A0270A0E4A630D00498DA9 /* file_util_mac.mm */; };
A5CE1D2B0E55F4D800AD0606 /* file_util_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5A0282D0E4CFA8500498DA9 /* file_util_unittest.cc */; };
AB4C147D0EC0E3F600655FED /* time_mac.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BEB81490D9B0F33009BA8DD /* time_mac.cc */; };
+ AB4FA13A0F2A101100D6572F /* event_recorder_stubs.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB4FA1390F2A101100D6572F /* event_recorder_stubs.cc */; };
ABE1BA2A0E7574D1009041DA /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABE1BA290E7574D1009041DA /* ApplicationServices.framework */; };
ABF4B98F0DC2BA6900A6E319 /* base_paths_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABF4B98E0DC2BA6900A6E319 /* base_paths_mac.mm */; };
ABF4B99E0DC2BB6000A6E319 /* clipboard_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABF4B99D0DC2BB6000A6E319 /* clipboard_mac.mm */; };
@@ -612,6 +613,7 @@
A5A0276B0E4BA33700498DA9 /* build_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = build_config.h; path = ../build/build_config.h; sourceTree = SOURCE_ROOT; };
A5A0282D0E4CFA8500498DA9 /* file_util_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util_unittest.cc; sourceTree = "<group>"; };
AB14B6060EBFA74C00FB3807 /* time_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time_posix.cc; sourceTree = "<group>"; };
+ AB4FA1390F2A101100D6572F /* event_recorder_stubs.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event_recorder_stubs.cc; sourceTree = "<group>"; };
ABE1BA290E7574D1009041DA /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = "<group>"; };
ABF4B98E0DC2BA6900A6E319 /* base_paths_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = base_paths_mac.mm; sourceTree = "<group>"; };
ABF4B99D0DC2BB6000A6E319 /* clipboard_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard_mac.mm; sourceTree = "<group>"; };
@@ -852,6 +854,7 @@
536092F80ECE474500D1B91E /* dtoa.cc */,
825402FF0D92D1BC0006B936 /* event_recorder.cc */,
825403000D92D1BC0006B936 /* event_recorder.h */,
+ AB4FA1390F2A101100D6572F /* event_recorder_stubs.cc */,
ABF68B270EB0F93100E72835 /* field_trial.h */,
ABF68B280EB0F93100E72835 /* field_trial.cc */,
ABF68B260EB0F93100E72835 /* field_trial_unittest.cc */,
@@ -1359,6 +1362,7 @@
7B78CE250E5314A000609465 /* debug_util.cc in Sources */,
7B78CE120E53131800609465 /* debug_util_posix.cc in Sources */,
536092FA0ECE474500D1B91E /* dtoa.cc in Sources */,
+ AB4FA13A0F2A101100D6572F /* event_recorder_stubs.cc in Sources */,
ABF68B2A0EB0F93100E72835 /* field_trial.cc in Sources */,
4D11B89E0E929F0400EF7617 /* file_path.cc in Sources */,
A5A026550E4A214600498DA9 /* file_util.cc in Sources */,
diff --git a/base/base_lib.scons b/base/base_lib.scons
index 7965c5e..93bf869 100644
--- a/base/base_lib.scons
+++ b/base/base_lib.scons
@@ -353,6 +353,7 @@ if env.Bit('posix'):
if env.Bit('mac'):
input_files.Extend([
'base_paths_mac.mm',
+ 'event_recorder_stubs.cc',
'clipboard_mac.mm',
'file_util_mac.mm',
'file_version_info_mac.mm',
@@ -372,6 +373,7 @@ if env.Bit('linux'):
'base_paths_linux.cc',
'clipboard_linux.cc',
'data_pack.cc',
+ 'event_recorder_stubs.cc',
'file_util_linux.cc',
'file_version_info_linux.cc',
'hmac_nss.cc',
diff --git a/base/event_recorder.cc b/base/event_recorder.cc
index ab7fcf9..0f1fb21 100644
--- a/base/event_recorder.cc
+++ b/base/event_recorder.cc
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/event_recorder.h"
+#include "build/build_config.h"
+#include <windows.h>
#include <mmsystem.h>
+#include "base/event_recorder.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/time.h"
diff --git a/base/event_recorder.h b/base/event_recorder.h
index a258d3a..43278c6 100644
--- a/base/event_recorder.h
+++ b/base/event_recorder.h
@@ -6,7 +6,9 @@
#define BASE_EVENT_RECORDER_H_
#include <string>
+#if defined(OS_WIN)
#include <windows.h>
+#endif
#include "base/basictypes.h"
namespace base {
@@ -55,10 +57,12 @@ class EventRecorder {
// Is the EventRecorder currently playing.
bool is_playing() const { return is_playing_; }
+#if defined(OS_WIN)
// C-style callbacks for the EventRecorder.
// Used for internal purposes only.
LRESULT RecordWndProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT PlaybackWndProc(int nCode, WPARAM wParam, LPARAM lParam);
+#endif
private:
// Create a new EventRecorder. Events are saved to the file filename.
@@ -67,8 +71,10 @@ class EventRecorder {
explicit EventRecorder()
: is_recording_(false),
is_playing_(false),
+#if defined(OS_WIN)
journal_hook_(NULL),
file_(NULL),
+#endif
playback_first_msg_time_(0),
playback_start_time_(0) {
}
@@ -78,9 +84,11 @@ class EventRecorder {
bool is_recording_;
bool is_playing_;
+#if defined(OS_WIN)
HHOOK journal_hook_;
FILE* file_;
EVENTMSG playback_msg_;
+#endif
int playback_first_msg_time_;
int playback_start_time_;
diff --git a/base/event_recorder_stubs.cc b/base/event_recorder_stubs.cc
new file mode 100644
index 0000000..9499c75
--- /dev/null
+++ b/base/event_recorder_stubs.cc
@@ -0,0 +1,28 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/event_recorder.h"
+
+// This file implements a link stub for EventRecorder that can be used on
+// platforms that don't have a working EventRecorder implementation.
+
+namespace base {
+
+EventRecorder* EventRecorder::current_; // Our singleton.
+
+bool EventRecorder::StartRecording(const std::wstring& filename) {
+ return true;
+}
+
+void EventRecorder::StopRecording() {
+}
+
+bool EventRecorder::StartPlayback(const std::wstring& filename) {
+ return false;
+}
+
+void EventRecorder::StopPlayback() {
+}
+
+} // namespace
diff --git a/webkit/tools/test_shell/SConscript b/webkit/tools/test_shell/SConscript
index 8bf73b2..4bdfea9 100644
--- a/webkit/tools/test_shell/SConscript
+++ b/webkit/tools/test_shell/SConscript
@@ -119,6 +119,7 @@ if env.Bit('windows'):
input_files.extend([
'drag_delegate.cc',
'drop_delegate.cc',
+ 'test_shell_platform_delegate_win.cc',
'test_shell_win.cc',
'test_webview_delegate_win.cc',
'webview_host_win.cc',
@@ -129,6 +130,7 @@ elif env.Bit('linux'):
'webview_host_gtk.cc',
'webwidget_host_gtk.cc',
'test_shell_gtk.cc',
+ 'test_shell_platform_delegate_gtk.cc',
'test_webview_delegate_gtk.cc',
])
diff --git a/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj b/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
index 902bbf3a..655d179 100644
--- a/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
+++ b/webkit/tools/test_shell/mac/TestShell.xcodeproj/project.pbxproj
@@ -85,6 +85,9 @@
93AF4F350EFAFE2C0073C62D /* GKURL_unittest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4F310EFAFE2C0073C62D /* GKURL_unittest.cpp */; };
93AF4F360EFAFE2C0073C62D /* ICOImageDecoder_unittest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4F320EFAFE2C0073C62D /* ICOImageDecoder_unittest.cpp */; };
93AF4F370EFAFE2C0073C62D /* XBMImageDecoder_unittest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4F330EFAFE2C0073C62D /* XBMImageDecoder_unittest.cpp */; };
+ AB19AC150F1BBBD000673E20 /* test_shell_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB19AC140F1BBBD000673E20 /* test_shell_main.cc */; };
+ AB19AC290F1BD6C900673E20 /* test_shell_platform_delegate_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB19AC280F1BD6C900673E20 /* test_shell_platform_delegate_mac.mm */; };
+ AB19AD380F1D0AF200673E20 /* test_shell_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA9CAE90DBC521D00CB1EFB /* test_shell_mac.mm */; };
E43A79AA0F1CE23800ABD5D1 /* textAreaResizeCorner.png in Resources */ = {isa = PBXBuildFile; fileRef = E43A79A90F1CE23800ABD5D1 /* textAreaResizeCorner.png */; };
E44662070ECCD652000B9316 /* test_webview_delegate.cc in Sources */ = {isa = PBXBuildFile; fileRef = E44662060ECCD652000B9316 /* test_webview_delegate.cc */; };
E450637E0E4100740025A81A /* test_shell_request_context.cc in Sources */ = {isa = PBXBuildFile; fileRef = E450637D0E4100740025A81A /* test_shell_request_context.cc */; };
@@ -193,11 +196,9 @@
E456290C0E26B4FE005E4685 /* test_shell_switches.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABCF253C0DB8436B00099567 /* test_shell_switches.cc */; };
E456290F0E26B4FE005E4685 /* webview_host.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8A785E0DC553EE005C27B8 /* webview_host.mm */; };
E45629100E26B4FE005E4685 /* webwidget_host.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABD16F380DC6A73B0013D3AA /* webwidget_host.mm */; };
- E45629150E26B4FE005E4685 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.mm */; };
E45629160E26B4FE005E4685 /* event_sending_controller.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB8A78520DC553A8005C27B8 /* event_sending_controller.cc */; };
E45629170E26B4FE005E4685 /* layout_test_controller.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB8A77FD0DC54DD6005C27B8 /* layout_test_controller.cc */; };
E45629190E26B4FE005E4685 /* test_navigation_controller.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB351E2E0DC7B290002F427A /* test_navigation_controller.cc */; };
- E456291A0E26B4FE005E4685 /* test_shell_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA9CAE90DBC521D00CB1EFB /* test_shell_mac.mm */; };
E456291C0E26B4FE005E4685 /* test_webview_delegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8A78580DC553D7005C27B8 /* test_webview_delegate.mm */; };
E456291D0E26B4FE005E4685 /* text_input_controller.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB8A785B0DC553E4005C27B8 /* text_input_controller.cc */; };
E456291E0E26B4FE005E4685 /* test_shell_webview.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABA65EFE0DD50BFF003A4FC8 /* test_shell_webview.mm */; };
@@ -721,7 +722,6 @@
/* Begin PBXFileReference section */
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = "<group>"; };
- 29B97316FDCFA39411CA2CEA /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = "<group>"; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = "<group>"; };
@@ -787,6 +787,11 @@
93AF4F310EFAFE2C0073C62D /* GKURL_unittest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GKURL_unittest.cpp; path = ../../webcore_unit_tests/GKURL_unittest.cpp; sourceTree = SOURCE_ROOT; };
93AF4F320EFAFE2C0073C62D /* ICOImageDecoder_unittest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ICOImageDecoder_unittest.cpp; path = ../../webcore_unit_tests/ICOImageDecoder_unittest.cpp; sourceTree = SOURCE_ROOT; };
93AF4F330EFAFE2C0073C62D /* XBMImageDecoder_unittest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = XBMImageDecoder_unittest.cpp; path = ../../webcore_unit_tests/XBMImageDecoder_unittest.cpp; sourceTree = SOURCE_ROOT; };
+ AB19AC140F1BBBD000673E20 /* test_shell_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_shell_main.cc; sourceTree = "<group>"; };
+ AB19AC1B0F1BC29D00673E20 /* test_shell_platform_delegate_win.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_shell_platform_delegate_win.cc; sourceTree = "<group>"; };
+ AB19AC1F0F1BD2D800673E20 /* test_shell_platform_delegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_shell_platform_delegate.h; sourceTree = "<group>"; };
+ AB19AC280F1BD6C900673E20 /* test_shell_platform_delegate_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = test_shell_platform_delegate_mac.mm; sourceTree = "<group>"; };
+ AB19AC2D0F1BD6E200673E20 /* test_shell_platform_delegate_gtk.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_shell_platform_delegate_gtk.cc; sourceTree = "<group>"; };
AB351E2E0DC7B290002F427A /* test_navigation_controller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_navigation_controller.cc; sourceTree = "<group>"; };
AB351E2F0DC7B290002F427A /* test_navigation_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = test_navigation_controller.h; sourceTree = "<group>"; };
AB8665450DC78A5A002CE06A /* googleurl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = googleurl.xcodeproj; path = build/googleurl.xcodeproj; sourceTree = "<group>"; };
@@ -1186,7 +1191,6 @@
F431EA490F1D141300E8D37F /* DumpRenderTreePasteboard.h */,
4D4164FA0F212E6500F2F4A0 /* KeystoneGlue.h */,
4D4164FB0F212E6500F2F4A0 /* KeystoneGlue.m */,
- 29B97316FDCFA39411CA2CEA /* main.mm */,
ABA65EFD0DD50BFF003A4FC8 /* test_shell_webview.h */,
ABA65EFE0DD50BFF003A4FC8 /* test_shell_webview.mm */,
32CA4F630368D1EE00C91783 /* TestShell_Prefix.pch */,
@@ -1277,6 +1281,11 @@
E45449360EC9FD15000DFA6E /* test_shell.cc */,
ABA9CAE80DBC521D00CB1EFB /* test_shell.h */,
ABA9CAE90DBC521D00CB1EFB /* test_shell_mac.mm */,
+ AB19AC140F1BBBD000673E20 /* test_shell_main.cc */,
+ AB19AC1F0F1BD2D800673E20 /* test_shell_platform_delegate.h */,
+ AB19AC2D0F1BD6E200673E20 /* test_shell_platform_delegate_gtk.cc */,
+ AB19AC280F1BD6C900673E20 /* test_shell_platform_delegate_mac.mm */,
+ AB19AC1B0F1BC29D00673E20 /* test_shell_platform_delegate_win.cc */,
E450637D0E4100740025A81A /* test_shell_request_context.cc */,
E450637C0E4100740025A81A /* test_shell_request_context.h */,
ABCF253C0DB8436B00099567 /* test_shell_switches.cc */,
@@ -1941,12 +1950,10 @@
E45629160E26B4FE005E4685 /* event_sending_controller.cc in Sources */,
4D4164FC0F212E6500F2F4A0 /* KeystoneGlue.m in Sources */,
E45629170E26B4FE005E4685 /* layout_test_controller.cc in Sources */,
- E45629150E26B4FE005E4685 /* main.mm in Sources */,
53E50D280ECA1B21001784B4 /* simple_clipboard_impl.cc in Sources */,
E456296A0E26B64D005E4685 /* simple_resource_loader_bridge.cc in Sources */,
E45629190E26B4FE005E4685 /* test_navigation_controller.cc in Sources */,
E45449370EC9FD15000DFA6E /* test_shell.cc in Sources */,
- E456291A0E26B4FE005E4685 /* test_shell_mac.mm in Sources */,
E450637E0E4100740025A81A /* test_shell_request_context.cc in Sources */,
E456290C0E26B4FE005E4685 /* test_shell_switches.cc in Sources */,
E456291E0E26B4FE005E4685 /* test_shell_webview.mm in Sources */,
@@ -1955,6 +1962,9 @@
E456291D0E26B4FE005E4685 /* text_input_controller.cc in Sources */,
E456290F0E26B4FE005E4685 /* webview_host.mm in Sources */,
E45629100E26B4FE005E4685 /* webwidget_host.mm in Sources */,
+ AB19AC150F1BBBD000673E20 /* test_shell_main.cc in Sources */,
+ AB19AC290F1BD6C900673E20 /* test_shell_platform_delegate_mac.mm in Sources */,
+ AB19AD380F1D0AF200673E20 /* test_shell_mac.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/webkit/tools/test_shell/mac/main.mm b/webkit/tools/test_shell/mac/main.mm
deleted file mode 100644
index 1f73d53..0000000
--- a/webkit/tools/test_shell/mac/main.mm
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-#include <sys/syslimits.h>
-#include <unistd.h>
-#import <mach/task.h>
-
-#include <string>
-
-#include "base/at_exit.h"
-#include "base/basictypes.h"
-#include "base/command_line.h"
-#include "base/file_util.h"
-#include "base/icu_util.h"
-#include "base/memory_debug.h"
-#include "base/message_loop.h"
-#include "base/path_service.h"
-#include "base/string_util.h"
-#include "net/base/cookie_monster.h"
-#include "net/http/http_cache.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
-#include "webkit/tools/test_shell/test_shell.h"
-#include "webkit/tools/test_shell/test_shell_request_context.h"
-#include "webkit/tools/test_shell/test_shell_switches.h"
-#import "webkit/tools/test_shell/mac/KeystoneGlue.h"
-
-#include "WebSystemInterface.h"
-
-static char g_currentTestName[PATH_MAX];
-
-static const char* kStatsFile = "testshell";
-static int kStatsFileThreads = 20;
-static int kStatsFileCounters = 100;
-
-// Extracts the name of the test from the given path and sets the test name
-// global.
-static void SetCurrentTestName(char* path) {
- char* lastSlash = strrchr(path, '/');
- if (lastSlash) {
- ++lastSlash;
- } else {
- lastSlash = path;
- }
-
- strncpy(g_currentTestName, lastSlash, PATH_MAX);
- g_currentTestName[PATH_MAX-1] = '\0';
-}
-
-// The application delegate, used to hook application termination so that we
-// can kill the TestShell object and do some other app-wide cleanup. Once we
-// go into the run-loop, we never come back to main.
-@interface TestShellAppDelegate : NSObject {
- @private
- TestShell* shell_; // strong
-}
-- (id)initWithShell:(TestShell*)shell;
-@end
-
-@implementation TestShellAppDelegate
-- (id)initWithShell:(TestShell*)shell {
- if ((self = [super init])) {
- shell_ = shell;
- }
- return self;
-}
-
-- (void)dealloc {
- // Flush any remaining messages. This ensures that any accumulated
- // Task objects get destroyed before we exit, which avoids noise in
- // purify leak-test results.
- MessageLoop::current()->RunAllPending();
-
- TestShell::ShutdownTestShell();
-
- // get rid of the stats table last, V8 relies on it
- StatsTable* table = StatsTable::current();
- StatsTable::set_current(NULL);
- delete table;
-
- TestShell::CleanupLogging();
-
- [super dealloc];
-}
-
-// Called because we're the NSApp's delegate. Destroy ourselves which forces
-// shutdown cleanup to be called.
-- (void)applicationWillTerminate:(id)sender {
- // commit suicide.
- [self release];
-}
-
-@end
-
-int main(const int argc, const char *argv[]) {
- InitWebCoreSystemInterface();
-
- // Some tests may use base::Singleton<>, thus we need to instantiate
- // the AtExitManager or else we will leak objects.
- base::AtExitManager at_exit_manager;
-
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- // Allocate a message loop for this thread. Although it is not used
- // directly, its constructor sets up some necessary state.
- MessageLoop main_message_loop(MessageLoop::TYPE_UI);
-
- // Force AppKit to init itself, but don't start the runloop yet
- [NSApplication sharedApplication];
- [NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
-
- // Interpret the same flags as
- // the windows version, so that we can run the same test scripts. stop
- // if we hit something that's not a switch (like, oh, a URL).
-
- CommandLine::Init(argc, argv);
- const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
-
- if (parsed_command_line.HasSwitch(test_shell::kCheckLayoutTestSystemDeps)) {
- // Always succeed the deps check, currently just used by windows port.
- exit(0);
- }
-
- if (parsed_command_line.HasSwitch(test_shell::kStartupDialog)) {
- //TODO: add alert to allow attaching via gdb before things really get going
- }
-
- if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) {
- std::wstring dir =
- parsed_command_line.GetSwitchValue(test_shell::kCrashDumps);
- // TODO: enable breakpad
- // new google_breakpad::ExceptionHandler(dir, 0, &MinidumpCallback, 0, true);
- }
-
- bool suppress_error_dialogs = (getenv("CHROME_HEADLESS") != NULL) ||
- parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
- parsed_command_line.HasSwitch(test_shell::kLayoutTests);
- bool layout_test_mode =
- parsed_command_line.HasSwitch(test_shell::kLayoutTests);
-
- TestShell::InitLogging(suppress_error_dialogs, layout_test_mode, false);
- TestShell::InitializeTestShell(layout_test_mode);
-
- bool no_tree = parsed_command_line.HasSwitch(test_shell::kNoTree);
-
- bool dump_pixels = parsed_command_line.HasSwitch(test_shell::kDumpPixels);
- std::wstring pixel_file_name;
- if (dump_pixels) {
- pixel_file_name =
- parsed_command_line.GetSwitchValue(test_shell::kDumpPixels);
- if (pixel_file_name.size() == 0) {
- fprintf(stderr, "No file specified for pixel tests");
- exit(1);
- }
- }
-
- if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
- const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
- test_shell::kTestShellTimeOut);
- int timeout_ms = static_cast<int>(StringToInt64(timeout_str.c_str()));
- if (timeout_ms > 0)
- TestShell::SetFileTestTimeout(timeout_ms);
- }
-
- std::wstring javascript_flags =
- parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
- // Test shell always exposes the GC.
- javascript_flags += L" --expose-gc";
- webkit_glue::SetJavaScriptFlags(javascript_flags);
-
- // Load and initialize the stats table (one per process, so that multiple
- // instances don't interfere with each other)
- char statsfile[64];
- snprintf(statsfile, 64, "%s-%d", kStatsFile, getpid());
- StatsTable *table =
- new StatsTable(statsfile, kStatsFileThreads, kStatsFileCounters);
- StatsTable::set_current(table);
-
- net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;
- bool playback_mode =
- parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
- bool record_mode =
- parsed_command_line.HasSwitch(test_shell::kRecordMode);
-
- if (playback_mode)
- cache_mode = net::HttpCache::PLAYBACK;
- else if (record_mode)
- cache_mode = net::HttpCache::RECORD;
-
- bool dump_stats_table =
- parsed_command_line.HasSwitch(test_shell::kDumpStatsTable);
-
- bool debug_memory_in_use =
- parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse);
-
- if (layout_test_mode ||
- parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
- net::CookieMonster::EnableFileScheme();
-
- std::wstring cache_path =
- parsed_command_line.GetSwitchValue(test_shell::kCacheDir);
- if (cache_path.empty()) {
- PathService::Get(base::DIR_EXE, &cache_path);
- file_util::AppendToPath(&cache_path, L"cache");
- }
-
- // Initializing with a default context, which means no on-disk cookie DB,
- // and no support for directory listings.
- SimpleResourceLoaderBridge::Init(
- new TestShellRequestContext(cache_path, cache_mode, layout_test_mode));
-
- // Load ICU data tables
- icu_util::Initialize();
-
- // Config the network module so it has access to a limited set of resources.
- // NetModule::SetResourceProvider(NetResourceProvider);
-
- // Treat the first loose value as the initial URL to open.
- std::wstring uri;
-
- // Default to a homepage if we're interactive
- if (!layout_test_mode) {
- // If Keystone is available, set it up if needed and register with it.
- [KeystoneGlue registerWithKeystone];
-
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- NSString *testShellPath =
- [resourcePath stringByAppendingPathComponent:@"test_shell/index.html"];
- // don't use NSURL; it puts a "localhost" bit in that freaks out our URL
- // handling
- NSString *testShellURL = [NSString stringWithFormat:@"file://%@",
- testShellPath];
- uri = UTF8ToWide([testShellURL UTF8String]);
- }
-
- std::vector<std::wstring> values = parsed_command_line.GetLooseValues();
- if (values.size() > 0)
- uri = values[0];
-
- TestShell* shell;
- if (TestShell::CreateNewWindow(uri, &shell)) {
-#ifdef NOTYET
- if (record_mode || playback_mode) {
- // Move the window to the upper left corner for consistent
- // record/playback mode. For automation, we want this to work
- // on build systems where the script invoking us is a background
- // process. So for this case, make our window the topmost window
- // as well.
- // ForegroundHelper::SetForeground(shell->mainWnd());
- // ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
- // Tell webkit as well.
- webkit_glue::SetRecordPlaybackMode(true);
- }
-#endif
- shell->Show(shell->webView(), NEW_WINDOW);
-
- if (dump_stats_table)
- shell->DumpStatsTableOnExit();
-
-#ifdef NOTYET
- if ((record_mode || playback_mode) && !no_events) {
- std::string script_path = cache_path;
- // Create the cache directory in case it doesn't exist.
- file_util::CreateDirectory(cache_path);
- file_util::AppendToPath(&script_path, "script.log");
- if (record_mode)
- base::EventRecorder::current()->StartRecording(script_path);
- if (playback_mode)
- base::EventRecorder::current()->StartPlayback(script_path);
- }
-#endif
-
- if (debug_memory_in_use) {
- base::MemoryDebug::SetMemoryInUseEnabled(true);
- base::MemoryDebug::DumpAllMemoryInUse();
- }
-
- // Set up our app delegate so we can tear down the TestShell object when
- // necessary. |delegate| takes ownership of |shell|, and will clean itself
- // up when it receives the notification that the app is terminating.
- TestShellAppDelegate* delegate = [[TestShellAppDelegate alloc]
- initWithShell:shell];
- [[NSApplication sharedApplication] setDelegate:delegate];
-
- if (layout_test_mode) {
- // If we die during tests, we don't want to be spamming the user's crash
- // reporter. Set our exception port to null.
- if (task_set_exception_ports(mach_task_self(),
- EXC_MASK_ALL,
- MACH_PORT_NULL,
- EXCEPTION_DEFAULT,
- THREAD_STATE_NONE) != KERN_SUCCESS) {
- return -1;
- }
-
- // Cocoa housekeeping
- [NSApp finishLaunching];
- webkit_glue::SetLayoutTestMode(true);
-
- // Set up for the kind of test requested.
- TestShell::TestParams params;
- if (dump_pixels) {
- // The pixel test flag also gives the image file name to use.
- params.dump_pixels = true;
- params.pixel_file_name = pixel_file_name;
- if (params.pixel_file_name.size() == 0) {
- fprintf(stderr, "No file specified for pixel tests");
- exit(1);
- }
- }
- if (no_tree)
- params.dump_tree = false;
- if (uri.length() == 0) {
- // Watch stdin for URLs.
- char filenameBuffer[2048];
- while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
- char *newLine = strchr(filenameBuffer, '\n');
- if (newLine)
- *newLine = '\0';
- if (!*filenameBuffer)
- continue;
-
- SetCurrentTestName(filenameBuffer);
- params.test_url = filenameBuffer;
- if (!TestShell::RunFileTest(params))
- break;
- }
- } else {
- params.test_url = WideToUTF8(uri).c_str();
- TestShell::RunFileTest(params);
- }
- } else {
- main_message_loop.Run();
- }
-
-#ifdef NOTYET
- if (record_mode)
- base::EventRecorder::current()->StopRecording();
- if (playback_mode)
- base::EventRecorder::current()->StopPlayback();
-#endif
- }
-
- [pool release];
- return 0;
-}
diff --git a/webkit/tools/test_shell/test_shell.vcproj b/webkit/tools/test_shell/test_shell.vcproj
index b652571..c7e2d96 100644
--- a/webkit/tools/test_shell/test_shell.vcproj
+++ b/webkit/tools/test_shell/test_shell.vcproj
@@ -266,6 +266,14 @@
>
</File>
<File
+ RelativePath=".\test_shell_platform_delegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_shell_platform_delegate_win.cc"
+ >
+ </File>
+ <File
RelativePath=".\test_shell_request_context.cc"
>
</File>
diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm
index 789fc4e..0d004a5 100644
--- a/webkit/tools/test_shell/test_shell_mac.mm
+++ b/webkit/tools/test_shell/test_shell_mac.mm
@@ -48,7 +48,10 @@
#define MAX_LOADSTRING 100
+// Sizes for URL bar layout
+#define BUTTON_HEIGHT 22
#define BUTTON_WIDTH 72
+#define BUTTON_MARGIN 8
#define URLBAR_HEIGHT 32
// Global Variables:
@@ -157,230 +160,14 @@ void TestShell::PlatformShutdown() {
[DumpRenderTreePasteboard releaseLocalPasteboards];
}
-#if OBJC_API_VERSION == 2
-static void SwizzleAllMethods(Class imposter, Class original) {
- unsigned int imposterMethodCount = 0;
- Method* imposterMethods = class_copyMethodList(imposter, &imposterMethodCount);
-
- unsigned int originalMethodCount = 0;
- Method* originalMethods = class_copyMethodList(original, &originalMethodCount);
-
- for (unsigned int i = 0; i < imposterMethodCount; i++) {
- SEL imposterMethodName = method_getName(imposterMethods[i]);
-
- // Attempt to add the method to the original class. If it fails, the method
- // already exists and we should instead exchange the implementations.
- if (class_addMethod(original,
- imposterMethodName,
- method_getImplementation(originalMethods[i]),
- method_getTypeEncoding(originalMethods[i]))) {
- continue;
- }
-
- unsigned int j = 0;
- for (; j < originalMethodCount; j++) {
- SEL originalMethodName = method_getName(originalMethods[j]);
- if (sel_isEqual(imposterMethodName, originalMethodName)) {
- break;
- }
- }
-
- // If class_addMethod failed above then the method must exist on the
- // original class.
- DCHECK(j < originalMethodCount) << "method wasn't found?";
- method_exchangeImplementations(imposterMethods[i], originalMethods[j]);
- }
-
- if (imposterMethods) {
- free(imposterMethods);
- }
- if (originalMethods) {
- free(originalMethods);
- }
-}
-#endif
-
-static void SwizzleNSPasteboard(void) {
- // We replace NSPaseboard w/ the shim (from WebKit) that avoids having
- // sideeffects w/ whatever the user does at the same time.
-
- Class imposterClass = objc_getClass("DumpRenderTreePasteboard");
- Class originalClass = objc_getClass("NSPasteboard");
-#if OBJC_API_VERSION == 0
- class_poseAs(imposterClass, originalClass);
-#else
- // Swizzle instance methods...
- SwizzleAllMethods(imposterClass, originalClass);
- // and then class methods.
- SwizzleAllMethods(object_getClass(imposterClass),
- object_getClass(originalClass));
-#endif
-}
-
-static void SetDefaultsToLayoutTestValues(void) {
- // So we can match the WebKit layout tests, we want to force a bunch of
- // preferences that control appearance to match.
- // (We want to do this as early as possible in application startup so
- // the settings are in before any higher layers could cache values.)
-
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-
- const NSInteger kMinFontSizeCGSmoothes = 4;
- const NSInteger kNoFontSmoothing = 0;
- const NSInteger kBlueTintedAppearance = 1;
- [defaults setInteger:kMinFontSizeCGSmoothes
- forKey:@"AppleAntiAliasingThreshold"];
- [defaults setInteger:kNoFontSmoothing
- forKey:@"AppleFontSmoothing"];
- [defaults setInteger:kBlueTintedAppearance
- forKey:@"AppleAquaColorVariant"];
- [defaults setObject:@"0.709800 0.835300 1.000000"
- forKey:@"AppleHighlightColor"];
- [defaults setObject:@"0.500000 0.500000 0.500000"
- forKey:@"AppleOtherHighlightColor"];
- [defaults setObject:[NSArray arrayWithObject:@"en"]
- forKey:@"AppleLanguages"];
-
- // AppKit pulls scrollbar style from NSUserDefaults. HIToolbox uses
- // CFPreferences, but AnyApplication, so we set it, force it to load, and
- // then reset the pref to what it was (HIToolbox will cache what it loaded).
- [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
- CFTypeRef initialValue
- = CFPreferencesCopyValue(CFSTR("AppleScrollBarVariant"),
- kCFPreferencesAnyApplication,
- kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
- CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"),
- CFSTR("DoubleMax"),
- kCFPreferencesAnyApplication,
- kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
- // Make HIToolbox read from CFPreferences
- ThemeScrollBarArrowStyle style;
- GetThemeScrollBarArrowStyle(&style);
- if (initialValue) {
- // Reset the preference to what it was
- CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"),
- initialValue,
- kCFPreferencesAnyApplication,
- kCFPreferencesCurrentUser,
- kCFPreferencesAnyHost);
- CFRelease(initialValue);
- }
-}
-
-static void ClearAnyDefaultsForLayoutTests(void) {
- // Not running a test, clear the keys so the TestShell looks right to the
- // running user.
-
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
-
- [defaults removeObjectForKey:@"AppleAntiAliasingThreshold"];
- [defaults removeObjectForKey:@"AppleFontSmoothing"];
- [defaults removeObjectForKey:@"AppleAquaColorVariant"];
- [defaults removeObjectForKey:@"AppleHighlightColor"];
- [defaults removeObjectForKey:@"AppleOtherHighlightColor"];
- [defaults removeObjectForKey:@"AppleLanguages"];
- [defaults removeObjectForKey:@"AppleScrollBarVariant"];
-}
-
-static CMProfileRef gUsersColorProfile = NULL;
-
-static void RestoreUsersColorProfile(void) {
- // This is called from the unsafe signal handers, so doing just about anything
- // isn't really safe. But since we're already gonna crash, we give it a try
- // anyways... (and WebKit uses this strategy...)
-
- if (gUsersColorProfile) {
- CGDirectDisplayID displayID = CGMainDisplayID();
- CMError error = CMSetProfileByAVID((UInt32)displayID, gUsersColorProfile);
- CMCloseProfile(gUsersColorProfile);
- if (error) {
- fprintf(stderr, "Failed to restore color profile, use System "
- "Preferences -> Displays -> Color to reset. Error: %d",
- (int)error);
- }
- gUsersColorProfile = NULL;
- }
-}
-
-static void SimpleSignalHandler(int sig) {
- // Try to restore and try to go down cleanly
- RestoreUsersColorProfile();
- exit(128 + sig);
-}
-
-static void CrashSignalHandler(int sig) {
- // Try to restore and get out fast...
- RestoreUsersColorProfile();
- _exit(128 + sig);
-}
-
-static void InstallLayoutTestColorProfile(void) {
- // To make sure we get consisten colors (not dependent on the Main display),
- // we force the generic rgb color profile. This cases a change the user can
- // see. We use the same basic method as WebKit for trying to make sure we
- // get the profile back if we go down in flames.
-
- // Save off the current
- CGDirectDisplayID displayID = CGMainDisplayID();
- CMProfileRef previousProfile;
- CMError error = CMGetProfileByAVID((UInt32)displayID, &previousProfile);
- if (error) {
- DLOG(WARNING) << "failed to get the current color profile, "
- "pixmaps won't match. Error: " << (int)error;
- return;
- }
-
- // Install the generic one
- NSColorSpace *genericSpace = [NSColorSpace genericRGBColorSpace];
- CMProfileRef genericProfile = (CMProfileRef)[genericSpace colorSyncProfile];
- if ((error = CMSetProfileByAVID((UInt32)displayID, genericProfile))) {
- DLOG(WARNING) << "failed install the generic color profile, "
- "pixmaps won't match. Error: " << (int)error;
- return;
- }
-
- // Save the starting profile, and hook in as best we can to make sure when
- // we exit, it's restored (use atexit() so direct calls to exit() call us).
- gUsersColorProfile = previousProfile;
- atexit(RestoreUsersColorProfile);
- // The less scary signals...
- signal(SIGINT, SimpleSignalHandler);
- signal(SIGHUP, SimpleSignalHandler);
- signal(SIGTERM, SimpleSignalHandler);
- // And now the scary ones...
- signal(SIGILL, CrashSignalHandler); // 4: illegal instruction
- signal(SIGTRAP, CrashSignalHandler); // 5: trace trap
- signal(SIGEMT, CrashSignalHandler); // 7: EMT instruction
- signal(SIGFPE, CrashSignalHandler); // 8: floating point exception
- signal(SIGBUS, CrashSignalHandler); // 10: bus error
- signal(SIGSEGV, CrashSignalHandler); // 11: segmentation violation
- signal(SIGSYS, CrashSignalHandler); // 12: bad argument to system call
- signal(SIGPIPE, CrashSignalHandler); // 13: write on a pipe with no reader
- signal(SIGXCPU, CrashSignalHandler); // 24: exceeded CPU time limit
- signal(SIGXFSZ, CrashSignalHandler); // 25: exceeded file size limit
-}
-
// static
void TestShell::InitializeTestShell(bool layout_test_mode) {
// This should move to a per-process platform-specific initialization function
// when one exists.
- [NSApplication sharedApplication];
window_list_ = new WindowList;
layout_test_mode_ = layout_test_mode;
- if (layout_test_mode_) {
- SwizzleNSPasteboard();
- SetDefaultsToLayoutTestValues();
- // If we could check the command line to see if we're doing pixel tests,
- // then we only install the color profile in that case.
- InstallLayoutTestColorProfile();
- } else {
- ClearAnyDefaultsForLayoutTests();
- }
-
web_prefs_ = new WebPreferences;
ResetWebPreferences();
@@ -450,8 +237,7 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
styleMask:(NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
- NSResizableWindowMask |
- NSTexturedBackgroundWindowMask)
+ NSResizableWindowMask )
backing:NSBackingStoreBuffered
defer:NO];
[m_mainWnd setTitle:@"TestShell"];
@@ -481,9 +267,10 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
// create buttons
NSRect button_rect = [[m_mainWnd contentView] bounds];
- button_rect.origin.y = window_rect.size.height - 22;
- button_rect.size.height = 22;
- button_rect.origin.x += 16;
+ button_rect.origin.y = window_rect.size.height - URLBAR_HEIGHT +
+ (URLBAR_HEIGHT - BUTTON_HEIGHT) / 2;
+ button_rect.size.height = BUTTON_HEIGHT;
+ button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = BUTTON_WIDTH;
NSView* content = [m_mainWnd contentView];
@@ -507,9 +294,9 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
[button setAction:@selector(stopLoading:)];
// text field for URL
- button_rect.origin.x += 16;
+ button_rect.origin.x += BUTTON_MARGIN;
button_rect.size.width = [[m_mainWnd contentView] bounds].size.width -
- button_rect.origin.x - 32;
+ button_rect.origin.x - BUTTON_MARGIN;
m_editWnd = [[NSTextField alloc] initWithFrame:button_rect];
[[m_mainWnd contentView] addSubview:m_editWnd];
[m_editWnd setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
@@ -595,7 +382,6 @@ void TestShell::TestFinished() {
puts("#TEST_TIMED_OUT\n");
puts("#EOF\n");
fflush(stdout);
- RestoreUsersColorProfile();
abort();
}
diff --git a/webkit/tools/test_shell/test_shell_main.cc b/webkit/tools/test_shell/test_shell_main.cc
index 3a52828..e895626 100644
--- a/webkit/tools/test_shell/test_shell_main.cc
+++ b/webkit/tools/test_shell/test_shell_main.cc
@@ -5,25 +5,10 @@
// Creates an instance of the test_shell.
#include "build/build_config.h"
-#include <stdlib.h> // required by _set_abort_behavior
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include <commctrl.h>
-#include "base/event_recorder.h"
-#include "base/gfx/native_theme.h"
-#include "base/resource_util.h"
-#include "base/win_util.h"
-#include "webkit/tools/test_shell/foreground_helper.h"
-#endif
-
-#if defined(OS_LINUX)
-#include <gtk/gtk.h>
-#endif
-
#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/command_line.h"
+#include "base/event_recorder.h"
#include "base/file_util.h"
#include "base/icu_util.h"
#include "base/memory_debug.h"
@@ -43,6 +28,7 @@
#include "webkit/glue/window_open_disposition.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
#include "webkit/tools/test_shell/test_shell_switches.h"
@@ -58,93 +44,26 @@ static const char* kStatsFilePrefix = "testshell_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;
-#if defined(OS_WIN)
-// This test approximates whether you have the Windows XP theme selected by
-// inspecting a couple of metrics. It does not catch all cases, but it does
-// pick up on classic vs xp, and normal vs large fonts. Something it misses
-// is changes to the color scheme (which will infact cause pixel test
-// failures).
-//
-// ** Expected dependencies **
-// + Theme: Windows XP
-// + Color scheme: Default (blue)
-// + Font size: Normal
-// + Font smoothing: off (minor impact).
-//
-bool HasLayoutTestThemeDependenciesWin() {
- // This metric will be 17 when font size is "Normal". The size of drop-down
- // menus depends on it.
- if (::GetSystemMetrics(SM_CXVSCROLL) != 17)
- return false;
-
- // Check that the system fonts RenderThemeWin relies on are Tahoma 11 pt.
- NONCLIENTMETRICS metrics;
- win_util::GetNonClientMetrics(&metrics);
- LOGFONTW* system_fonts[] =
- { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };
-
- for (size_t i = 0; i < arraysize(system_fonts); ++i) {
- if (system_fonts[i]->lfHeight != -11 ||
- 0 != wcscmp(L"Tahoma", system_fonts[i]->lfFaceName))
- return false;
- }
- return true;
-}
-
-bool CheckLayoutTestSystemDependenciesWin() {
- bool has_deps = HasLayoutTestThemeDependenciesWin();
- if (!has_deps) {
- fprintf(stderr,
- "\n"
- "###############################################################\n"
- "## Layout test system dependencies check failed.\n"
- "## Some layout tests may fail due to unexpected theme.\n"
- "##\n"
- "## To fix, go to Display Properties -> Appearance, and select:\n"
- "## + Windows and buttons: Windows XP style\n"
- "## + Color scheme: Default (blue)\n"
- "## + Font size: Normal\n"
- "###############################################################\n");
- }
- return has_deps;
-}
-
-#endif
-
-bool CheckLayoutTestSystemDependencies() {
-#if defined(OS_WIN)
- return CheckLayoutTestSystemDependenciesWin();
-#else
- return true;
-#endif
-}
-
} // namespace
-
int main(int argc, char* argv[]) {
base::EnableTerminationOnHeapCorruption();
-#ifdef _CRTDBG_MAP_ALLOC
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
-#endif
+
// Some tests may use base::Singleton<>, thus we need to instanciate
// the AtExitManager or else we will leak objects.
base::AtExitManager at_exit_manager;
-#if defined(OS_LINUX)
- gtk_init(&argc, &argv);
-#endif
-
- // Only parse the command line after GTK's had a crack at it.
+ TestShellPlatformDelegate::PreflightArgs(&argc, &argv);
CommandLine::Init(argc, argv);
-
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
+
+ TestShellPlatformDelegate platform(parsed_command_line);
+
if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
TestShell::ShowStartupDebuggingDialog();
if (parsed_command_line.HasSwitch(test_shell::kCheckLayoutTestSystemDeps)) {
- exit(CheckLayoutTestSystemDependencies() ? 0 : 1);
+ exit(platform.CheckLayoutTestSystemDependencies() ? 0 : 1);
}
// Allocate a message loop for this thread. Although it is not used
@@ -159,10 +78,8 @@ int main(int argc, char* argv[]) {
parsed_command_line.HasSwitch(test_shell::kLayoutTests);
bool enable_gp_fault_error_box = false;
-#if defined(OS_WIN)
enable_gp_fault_error_box =
parsed_command_line.HasSwitch(test_shell::kGPFaultErrorBox);
-#endif
TestShell::InitLogging(suppress_error_dialogs,
layout_test_mode,
enable_gp_fault_error_box);
@@ -172,11 +89,9 @@ int main(int argc, char* argv[]) {
// Suppress abort message in v8 library in debugging mode.
// V8 calls abort() when it hits assertion errors.
-#if defined(OS_WIN)
if (suppress_error_dialogs) {
- _set_abort_behavior(0, _WRITE_ABORT_MSG);
+ platform.SuppressErrorReporting();
}
-#endif
if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
base::TraceLog::StartTracing();
@@ -211,16 +126,7 @@ int main(int argc, char* argv[]) {
// Load ICU data tables
icu_util::Initialize();
- // Config the network module so it has access to a limited set of resources.
- net::NetModule::SetResourceProvider(TestShell::NetResourceProvider);
-
-#if defined(OS_WIN)
- INITCOMMONCONTROLSEX InitCtrlEx;
-
- InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
- InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
- InitCommonControlsEx(&InitCtrlEx);
-#endif
+ platform.InitializeGUI();
TestShell::InitializeTestShell(layout_test_mode);
@@ -229,16 +135,7 @@ int main(int argc, char* argv[]) {
// Disable user themes for layout tests so pixel tests are consistent.
if (layout_test_mode) {
-#if defined(OS_WIN)
- gfx::NativeTheme::instance()->DisableTheming();
-#elif defined(OS_LINUX)
- // Pick a theme that uses Cairo for drawing, since we:
- // 1) currently don't support GTK themes that use the GDK drawing APIs, and
- // 2) need to use a unified theme for layout tests anyway.
- g_object_set(gtk_settings_get_default(),
- "gtk-theme-name", "Mist",
- NULL);
-#endif
+ platform.SelectUnifiedTheme();
}
if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
@@ -249,11 +146,6 @@ int main(int argc, char* argv[]) {
TestShell::SetFileTestTimeout(timeout_ms);
}
-#if defined(OS_WIN)
- // Initialize global strings
- TestShell::RegisterWindowClass();
-#endif
-
// Treat the first loose value as the initial URL to open.
std::wstring uri;
@@ -281,33 +173,26 @@ int main(int argc, char* argv[]) {
// Load and initialize the stats table. Attempt to construct a somewhat
// unique name to isolate separate instances from each other.
StatsTable *table = new StatsTable(
- kStatsFilePrefix + Uint64ToString(base::RandUint64()),
+ // truncate the random # to 32 bits for the benefit of Mac OS X, to
+ // avoid tripping over its maximum shared memory segment name length
+ kStatsFilePrefix + Uint64ToString(base::RandUint64() & 0xFFFFFFFFL),
kStatsFileThreads,
kStatsFileCounters);
StatsTable::set_current(table);
TestShell* shell;
if (TestShell::CreateNewWindow(uri, &shell)) {
-#if defined(OS_WIN)
if (record_mode || playback_mode) {
- // Move the window to the upper left corner for consistent
- // record/playback mode. For automation, we want this to work
- // on build systems where the script invoking us is a background
- // process. So for this case, make our window the topmost window
- // as well.
- ForegroundHelper::SetForeground(shell->mainWnd());
- ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
+ platform.SetWindowPositionForRecording(shell);
// Tell webkit as well.
webkit_glue::SetRecordPlaybackMode(true);
}
-#endif
shell->Show(shell->webView(), NEW_WINDOW);
if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
shell->DumpStatsTableOnExit();
-#if defined(OS_WIN)
bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
if ((record_mode || playback_mode) && !no_events) {
std::wstring script_path = cache_path;
@@ -319,7 +204,6 @@ int main(int argc, char* argv[]) {
if (playback_mode)
base::EventRecorder::current()->StartPlayback(script_path);
}
-#endif
if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
base::MemoryDebug::SetMemoryInUseEnabled(true);
@@ -382,12 +266,10 @@ int main(int argc, char* argv[]) {
// purify leak-test results.
MessageLoop::current()->RunAllPending();
-#if defined(OS_WIN)
if (record_mode)
base::EventRecorder::current()->StopRecording();
if (playback_mode)
base::EventRecorder::current()->StopPlayback();
-#endif
}
TestShell::ShutdownTestShell();
@@ -397,8 +279,5 @@ int main(int argc, char* argv[]) {
StatsTable::set_current(NULL);
delete table;
-#ifdef _CRTDBG_MAP_ALLOC
- _CrtDumpMemoryLeaks();
-#endif
return 0;
}
diff --git a/webkit/tools/test_shell/test_shell_platform_delegate.h b/webkit/tools/test_shell/test_shell_platform_delegate.h
new file mode 100644
index 0000000..5be147a
--- /dev/null
+++ b/webkit/tools/test_shell/test_shell_platform_delegate.h
@@ -0,0 +1,58 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TestShellPlatformDelegate isolates a variety of platform-specific
+// functions so that code can invoke them by purpose without resorting to
+// ifdefs or runtime platform checks. Each platform should define an
+// implementation of this class. In many cases, implementation of methods
+// in this class will be stubs on platforms where those functions are
+// unnecessary.
+
+class TestShellPlatformDelegate {
+ public:
+ // The TestShellPlatformDelegate object is scoped to main(), and so
+ // its constructor is a good place to put per-application initialization
+ // (as opposed to per-test code, which should go into the TestShell class).
+ TestShellPlatformDelegate(const CommandLine& command_line);
+ ~TestShellPlatformDelegate();
+
+ // EnableMemoryDebugging: turn on platform memory debugging assistance
+ // (console messages, heap checking, leak detection, etc.).
+ void EnableMemoryDebugging();
+
+ // CheckLayoutTestSystemDependencies: check for any system dependencies that
+ // can't be easily overridden from within an application (for example, UI or
+ // display settings). Returns false if any dependencies are not met.
+ bool CheckLayoutTestSystemDependencies();
+
+ // PreflightArgs: give the platform first crack at the arguments to main()
+ // before we parse the command line. For example, some UI toolkits have
+ // runtime flags that they can pre-filter.
+ static void PreflightArgs(int* argc, char*** argv);
+
+ // SuppressErrorReporting: if possible, turn off platform error reporting
+ // dialogs, crash dumps, etc.
+ void SuppressErrorReporting();
+
+ // InitializeGUI: do any special initialization that the UI needs before
+ // we start the main message loop
+ void InitializeGUI();
+
+ // SelectUnifiedTheme: override user preferences so that the UI theme matches
+ // what's in the baseline files. Whenever possible, override user settings
+ // here rather than testing them in CheckLayoutTestSystemDependencies.
+ void SelectUnifiedTheme();
+
+ // AboutToExit: give the platform delegate a last chance to restore platform
+ // settings. Normally called by the destructor, but also called before
+ // abort() (example: test timeouts).
+ void AboutToExit();
+
+ // SetWindowPositionForRecording: if the platform's implementation of
+ // EventRecorder requires the window to be in a particular absolute position,
+ // make it so. This is called by TestShell after it creates the window.
+ void SetWindowPositionForRecording(TestShell *shell);
+ private:
+ const CommandLine& command_line_;
+};
diff --git a/webkit/tools/test_shell/test_shell_platform_delegate_gtk.cc b/webkit/tools/test_shell/test_shell_platform_delegate_gtk.cc
new file mode 100644
index 0000000..8846f19
--- /dev/null
+++ b/webkit/tools/test_shell/test_shell_platform_delegate_gtk.cc
@@ -0,0 +1,44 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h> // required by _set_abort_behavior
+#include <gtk/gtk.h>
+
+#include "base/command_line.h"
+#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
+
+void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
+ gtk_init(argc, argv);
+}
+
+void TestShellPlatformDelegate::SelectUnifiedTheme() {
+ // Pick a theme that uses Cairo for drawing, since we:
+ // 1) currently don't support GTK themes that use the GDK drawing APIs, and
+ // 2) need to use a unified theme for layout tests anyway.
+ g_object_set(gtk_settings_get_default(),
+ "gtk-theme-name", "Mist",
+ NULL);
+}
+
+TestShellPlatformDelegate::TestShellPlatformDelegate(
+ const CommandLine& command_line)
+ : command_line_(command_line) {
+}
+
+bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
+ return true;
+}
+
+void TestShellPlatformDelegate::SuppressErrorReporting() {
+}
+
+void TestShellPlatformDelegate::InitializeGUI() {
+}
+
+void TestShellPlatformDelegate::SetWindowPositionForRecording(TestShell *) {
+}
+
+TestShellPlatformDelegate::~TestShellPlatformDelegate() {
+}
diff --git a/webkit/tools/test_shell/test_shell_platform_delegate_mac.mm b/webkit/tools/test_shell/test_shell_platform_delegate_mac.mm
new file mode 100644
index 0000000..3642e35
--- /dev/null
+++ b/webkit/tools/test_shell/test_shell_platform_delegate_mac.mm
@@ -0,0 +1,286 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+
+// #include <Carbon/Carbon.h>
+// #include <ApplicationServices/ApplicationServices.h>
+#import <Cocoa/Cocoa.h>
+#import <objc/objc-runtime.h>
+#include <sys/syslimits.h>
+#include <unistd.h>
+#include <string>
+#include <stdlib.h>
+#include <mach/task.h>
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
+#include "webkit/tools/test_shell/test_shell_switches.h"
+#include "WebSystemInterface.h"
+
+static NSAutoreleasePool *gTestShellAutoreleasePool = nil;
+
+static void SetDefaultsToLayoutTestValues(void) {
+ // So we can match the WebKit layout tests, we want to force a bunch of
+ // preferences that control appearance to match.
+ // (We want to do this as early as possible in application startup so
+ // the settings are in before any higher layers could cache values.)
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+
+ const NSInteger kMinFontSizeCGSmoothes = 4;
+ const NSInteger kNoFontSmoothing = 0;
+ const NSInteger kBlueTintedAppearance = 1;
+ [defaults setInteger:kMinFontSizeCGSmoothes
+ forKey:@"AppleAntiAliasingThreshold"];
+ [defaults setInteger:kNoFontSmoothing
+ forKey:@"AppleFontSmoothing"];
+ [defaults setInteger:kBlueTintedAppearance
+ forKey:@"AppleAquaColorVariant"];
+ [defaults setObject:@"0.709800 0.835300 1.000000"
+ forKey:@"AppleHighlightColor"];
+ [defaults setObject:@"0.500000 0.500000 0.500000"
+ forKey:@"AppleOtherHighlightColor"];
+ [defaults setObject:[NSArray arrayWithObject:@"en"]
+ forKey:@"AppleLanguages"];
+
+ // AppKit pulls scrollbar style from NSUserDefaults. HIToolbox uses
+ // CFPreferences, but AnyApplication, so we set it, force it to load, and
+ // then reset the pref to what it was (HIToolbox will cache what it loaded).
+ [defaults setObject:@"DoubleMax" forKey:@"AppleScrollBarVariant"];
+ CFTypeRef initialValue =
+ CFPreferencesCopyValue(CFSTR("AppleScrollBarVariant"),
+ kCFPreferencesAnyApplication,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"),
+ CFSTR("DoubleMax"),
+ kCFPreferencesAnyApplication,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+ // Make HIToolbox read from CFPreferences
+ ThemeScrollBarArrowStyle style;
+ GetThemeScrollBarArrowStyle(&style);
+ if (initialValue) {
+ // Reset the preference to what it was
+ CFPreferencesSetValue(CFSTR("AppleScrollBarVariant"),
+ initialValue,
+ kCFPreferencesAnyApplication,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+ CFRelease(initialValue);
+ }
+}
+
+static void ClearAnyDefaultsForLayoutTests(void) {
+ // Not running a test, clear the keys so the TestShell looks right to the
+ // running user.
+
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+
+ [defaults removeObjectForKey:@"AppleAntiAliasingThreshold"];
+ [defaults removeObjectForKey:@"AppleFontSmoothing"];
+ [defaults removeObjectForKey:@"AppleAquaColorVariant"];
+ [defaults removeObjectForKey:@"AppleHighlightColor"];
+ [defaults removeObjectForKey:@"AppleOtherHighlightColor"];
+ [defaults removeObjectForKey:@"AppleLanguages"];
+ [defaults removeObjectForKey:@"AppleScrollBarVariant"];
+}
+
+static CMProfileRef gUsersColorProfile = NULL;
+
+static void RestoreUsersColorProfile(void) {
+ // This is called from the unsafe signal handers, so doing just about anything
+ // isn't really safe. But since we're already gonna crash, we give it a try
+ // anyways... (and WebKit uses this strategy...)
+
+ if (gUsersColorProfile) {
+ CGDirectDisplayID displayID = CGMainDisplayID();
+ CMError error = CMSetProfileByAVID((UInt32)displayID, gUsersColorProfile);
+ CMCloseProfile(gUsersColorProfile);
+ if (error) {
+ fprintf(stderr, "Failed to restore color profile, use System "
+ "Preferences -> Displays -> Color to reset. Error: %d",
+ (int)error);
+ }
+ gUsersColorProfile = NULL;
+ }
+}
+
+static void SimpleSignalHandler(int sig) {
+ // Try to restore and try to go down cleanly
+ RestoreUsersColorProfile();
+ exit(128 + sig);
+}
+
+static void CrashSignalHandler(int sig) {
+ // Try to restore and get out fast...
+ RestoreUsersColorProfile();
+ _exit(128 + sig);
+}
+
+static void InstallLayoutTestColorProfile(void) {
+ // To make sure we get consisten colors (not dependent on the Main display),
+ // we force the generic rgb color profile. This cases a change the user can
+ // see. We use the same basic method as WebKit for trying to make sure we
+ // get the profile back if we go down in flames.
+
+ // Save off the current
+ CGDirectDisplayID displayID = CGMainDisplayID();
+ CMProfileRef previousProfile;
+ CMError error = CMGetProfileByAVID((UInt32)displayID, &previousProfile);
+ if (error) {
+ DLOG(WARNING) << "failed to get the current color profile, "
+ "pixmaps won't match. Error: " << (int)error;
+ return;
+ }
+
+ // Install the generic one
+ NSColorSpace *genericSpace = [NSColorSpace genericRGBColorSpace];
+ CMProfileRef genericProfile = (CMProfileRef)[genericSpace colorSyncProfile];
+ if ((error = CMSetProfileByAVID((UInt32)displayID, genericProfile))) {
+ DLOG(WARNING) << "failed install the generic color profile, "
+ "pixmaps won't match. Error: " << (int)error;
+ return;
+ }
+
+ // Save the starting profile, and hook in as best we can to make sure when
+ // we exit, it's restored (use atexit() so direct calls to exit() call us).
+ gUsersColorProfile = previousProfile;
+ atexit(RestoreUsersColorProfile);
+ // The less scary signals...
+ signal(SIGINT, SimpleSignalHandler);
+ signal(SIGHUP, SimpleSignalHandler);
+ signal(SIGTERM, SimpleSignalHandler);
+ // And now the scary ones...
+ signal(SIGABRT, CrashSignalHandler); // abort() called
+ signal(SIGILL, CrashSignalHandler); // 4: illegal instruction
+ signal(SIGTRAP, CrashSignalHandler); // 5: trace trap
+ signal(SIGEMT, CrashSignalHandler); // 7: EMT instruction
+ signal(SIGFPE, CrashSignalHandler); // 8: floating point exception
+ signal(SIGBUS, CrashSignalHandler); // 10: bus error
+ signal(SIGSEGV, CrashSignalHandler); // 11: segmentation violation
+ signal(SIGSYS, CrashSignalHandler); // 12: bad argument to system call
+ signal(SIGPIPE, CrashSignalHandler); // 13: write on a pipe with no reader
+ signal(SIGXCPU, CrashSignalHandler); // 24: exceeded CPU time limit
+ signal(SIGXFSZ, CrashSignalHandler); // 25: exceeded file size limit
+}
+
+#if OBJC_API_VERSION == 2
+static void SwizzleAllMethods(Class imposter, Class original) {
+ unsigned int imposterMethodCount = 0;
+ Method* imposterMethods = class_copyMethodList(imposter, &imposterMethodCount);
+
+ unsigned int originalMethodCount = 0;
+ Method* originalMethods = class_copyMethodList(original, &originalMethodCount);
+
+ for (unsigned int i = 0; i < imposterMethodCount; i++) {
+ SEL imposterMethodName = method_getName(imposterMethods[i]);
+
+ // Attempt to add the method to the original class. If it fails, the method
+ // already exists and we should instead exchange the implementations.
+ if (class_addMethod(original,
+ imposterMethodName,
+ method_getImplementation(originalMethods[i]),
+ method_getTypeEncoding(originalMethods[i]))) {
+ continue;
+ }
+
+ unsigned int j = 0;
+ for (; j < originalMethodCount; j++) {
+ SEL originalMethodName = method_getName(originalMethods[j]);
+ if (sel_isEqual(imposterMethodName, originalMethodName)) {
+ break;
+ }
+ }
+
+ // If class_addMethod failed above then the method must exist on the
+ // original class.
+ DCHECK(j < originalMethodCount) << "method wasn't found?";
+ method_exchangeImplementations(imposterMethods[i], originalMethods[j]);
+ }
+
+ if (imposterMethods) {
+ free(imposterMethods);
+ }
+ if (originalMethods) {
+ free(originalMethods);
+ }
+}
+#endif
+
+static void SwizzleNSPasteboard(void) {
+ // We replace NSPaseboard w/ the shim (from WebKit) that avoids having
+ // sideeffects w/ whatever the user does at the same time.
+
+ Class imposterClass = objc_getClass("DumpRenderTreePasteboard");
+ Class originalClass = objc_getClass("NSPasteboard");
+#if OBJC_API_VERSION == 0
+ class_poseAs(imposterClass, originalClass);
+#else
+ // Swizzle instance methods...
+ SwizzleAllMethods(imposterClass, originalClass);
+ // and then class methods.
+ SwizzleAllMethods(object_getClass(imposterClass),
+ object_getClass(originalClass));
+#endif
+}
+
+TestShellPlatformDelegate::TestShellPlatformDelegate(
+ const CommandLine &command_line)
+ : command_line_(command_line) {
+ gTestShellAutoreleasePool = [[NSAutoreleasePool alloc] init];
+ InitWebCoreSystemInterface();
+ // Force AppKit to init itself, but don't start the runloop yet
+ [NSApplication sharedApplication];
+ [NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
+}
+
+TestShellPlatformDelegate::~TestShellPlatformDelegate() {
+ // if we have changed the user's display color profile for pixel tests,
+ // restore it.
+ RestoreUsersColorProfile();
+ [gTestShellAutoreleasePool release];
+}
+
+bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
+ return true;
+}
+
+void TestShellPlatformDelegate::InitializeGUI() {
+ if (command_line_.HasSwitch(test_shell::kLayoutTests)) {
+ // If we're doing automated testing, we won't be using a conventional
+ // run loop, so tell Cocoa to finish initializing.
+ [NSApp finishLaunching];
+ }
+}
+
+void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
+}
+
+void TestShellPlatformDelegate::SetWindowPositionForRecording(TestShell *) {
+}
+
+void TestShellPlatformDelegate::SelectUnifiedTheme() {
+ if (command_line_.HasSwitch(test_shell::kLayoutTests)) {
+ SetDefaultsToLayoutTestValues();
+ SwizzleNSPasteboard();
+
+ if (command_line_.HasSwitch(test_shell::kDumpPixels)) {
+ InstallLayoutTestColorProfile();
+ }
+ } else {
+ ClearAnyDefaultsForLayoutTests();
+ }
+}
+
+void TestShellPlatformDelegate::SuppressErrorReporting() {
+ // If we die during tests, we don't want to be spamming the user's crash
+ // reporter. Set our exception port to null.
+ task_set_exception_ports(mach_task_self(), EXC_MASK_ALL, MACH_PORT_NULL,
+ EXCEPTION_DEFAULT, THREAD_STATE_NONE);
+}
+
diff --git a/webkit/tools/test_shell/test_shell_platform_delegate_win.cc b/webkit/tools/test_shell/test_shell_platform_delegate_win.cc
new file mode 100644
index 0000000..d03dc5f
--- /dev/null
+++ b/webkit/tools/test_shell/test_shell_platform_delegate_win.cc
@@ -0,0 +1,110 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <windows.h>
+#include <commctrl.h>
+#include "base/command_line.h"
+#include "base/event_recorder.h"
+#include "base/gfx/native_theme.h"
+#include "base/resource_util.h"
+#include "base/win_util.h"
+#include "webkit/tools/test_shell/foreground_helper.h"
+#include "webkit/tools/test_shell/test_shell.h"
+#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
+
+TestShellPlatformDelegate::TestShellPlatformDelegate(
+ const CommandLine& command_line)
+ : command_line_(command_line) {
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
+#endif
+}
+
+TestShellPlatformDelegate::~TestShellPlatformDelegate() {
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtDumpMemoryLeaks();
+#endif
+}
+
+void TestShellPlatformDelegate::PreflightArgs(int *argc, char ***argv) {
+}
+
+// This test approximates whether you have the Windows XP theme selected by
+// inspecting a couple of metrics. It does not catch all cases, but it does
+// pick up on classic vs xp, and normal vs large fonts. Something it misses
+// is changes to the color scheme (which will infact cause pixel test
+// failures).
+//
+// ** Expected dependencies **
+// + Theme: Windows XP
+// + Color scheme: Default (blue)
+// + Font size: Normal
+// + Font smoothing: off (minor impact).
+//
+static bool HasLayoutTestThemeDependenciesWin() {
+ // This metric will be 17 when font size is "Normal". The size of drop-down
+ // menus depends on it.
+ if (::GetSystemMetrics(SM_CXVSCROLL) != 17)
+ return false;
+
+ // Check that the system fonts RenderThemeWin relies on are Tahoma 11 pt.
+ NONCLIENTMETRICS metrics;
+ win_util::GetNonClientMetrics(&metrics);
+ LOGFONTW* system_fonts[] =
+ { &metrics.lfStatusFont, &metrics.lfMenuFont, &metrics.lfSmCaptionFont };
+
+ for (size_t i = 0; i < arraysize(system_fonts); ++i) {
+ if (system_fonts[i]->lfHeight != -11 ||
+ 0 != wcscmp(L"Tahoma", system_fonts[i]->lfFaceName))
+ return false;
+ }
+ return true;
+}
+
+bool TestShellPlatformDelegate::CheckLayoutTestSystemDependencies() {
+ bool has_deps = HasLayoutTestThemeDependenciesWin();
+ if (!has_deps) {
+ fprintf(stderr,
+ "\n"
+ "###############################################################\n"
+ "## Layout test system dependencies check failed.\n"
+ "## Some layout tests may fail due to unexpected theme.\n"
+ "##\n"
+ "## To fix, go to Display Properties -> Appearance, and select:\n"
+ "## + Windows and buttons: Windows XP style\n"
+ "## + Color scheme: Default (blue)\n"
+ "## + Font size: Normal\n"
+ "###############################################################\n");
+ }
+ return has_deps;
+}
+
+void TestShellPlatformDelegate::SuppressErrorReporting() {
+ _set_abort_behavior(0, _WRITE_ABORT_MSG);
+}
+
+void TestShellPlatformDelegate::InitializeGUI() {
+ INITCOMMONCONTROLSEX InitCtrlEx;
+
+ InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
+ InitCommonControlsEx(&InitCtrlEx);
+ TestShell::RegisterWindowClass();
+}
+
+void TestShellPlatformDelegate::SelectUnifiedTheme() {
+ gfx::NativeTheme::instance()->DisableTheming();
+}
+
+void TestShellPlatformDelegate::SetWindowPositionForRecording(
+ TestShell *shell) {
+ // Move the window to the upper left corner for consistent
+ // record/playback mode. For automation, we want this to work
+ // on build systems where the script invoking us is a background
+ // process. So for this case, make our window the topmost window
+ // as well.
+ ForegroundHelper::SetForeground(shell->mainWnd());
+ ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
+}
diff --git a/webkit/tools/test_shell/test_shell_tests.vcproj b/webkit/tools/test_shell/test_shell_tests.vcproj
index 2b0bb22..3251e8c 100644
--- a/webkit/tools/test_shell/test_shell_tests.vcproj
+++ b/webkit/tools/test_shell/test_shell_tests.vcproj
@@ -226,6 +226,14 @@
RelativePath=".\resources\test_shell.rc"
>
</File>
+ <File
+ RelativePath=".\test_shell_platform_delegate.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_shell_platform_delegate_win.cc"
+ >
+ </File>
<File
RelativePath=".\test_shell_request_context.cc"
>
diff --git a/webkit/tools/test_shell/test_shell_win.cc b/webkit/tools/test_shell/test_shell_win.cc
index 28fabc5..3f82fe8 100644
--- a/webkit/tools/test_shell/test_shell_win.cc
+++ b/webkit/tools/test_shell/test_shell_win.cc
@@ -22,6 +22,7 @@
#include "base/trace_event.h"
#include "base/win_util.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
+#include "net/base/net_module.h"
#include "net/http/http_network_layer.h"
#include "net/url_request/url_request_file_job.h"
#include "skia/ext/bitmap_platform_device.h"
@@ -126,7 +127,7 @@ FilePath GetResourcesFilePath() {
return path.AppendASCII("resources");
}
-StringPiece GetRawDataResource(HMODULE module, int resource_id) {
+static StringPiece GetRawDataResource(HMODULE module, int resource_id) {
void* data_ptr;
size_t data_size;
return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
@@ -134,6 +135,11 @@ StringPiece GetRawDataResource(HMODULE module, int resource_id) {
StringPiece(static_cast<char*>(data_ptr), data_size) : StringPiece();
}
+// This is called indirectly by the network layer to access resources.
+StringPiece NetResourceProvider(int key) {
+ return GetRawDataResource(::GetModuleHandle(NULL), key);
+}
+
} // namespace
// Initialize static member variable
@@ -143,6 +149,8 @@ HINSTANCE TestShell::instance_handle_;
// static methods on TestShell
void TestShell::InitializeTestShell(bool layout_test_mode) {
+ net::NetModule::SetResourceProvider(NetResourceProvider);
+
// Start COM stuff.
HRESULT res = OleInitialize(NULL);
DCHECK(SUCCEEDED(res));